Using textscan in Matlab to handle data not properly formatted data - matlab

I'm using textscan to import data. I can get to it successfully import properly formatted data. I can't get it to properly handle data that isn't properly formatted. Below is the format of the data.
JeB2021Da 12-13 and stuff, 1, 1, 0, 1, 0, 1, 1, 1, 3, 1, 99, 0, 0, 0,
JoB2021Ha 12-13 and stuff, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 99, 2, 1, 0,
JoP2021Co 12-13 and stuff, not enough samples
MaA2021Be 12-13 and stuff, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 99, 1, 0, 0,
MaA2021Ma 12-13 and stuff, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 99, 1, 0, 0,
How would I handle the data that is, not enough samples? Because currently the data structures don't line up. The data structures that are being produced are 17 x 1 and 16 x 14. I'd like to import the string as it is in the data. So not enough samples would be imported. Below is the code that I'm using.
fid = fopen('./file.txt','r');
fmt = ['%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d'];
d = textscan(fid, fmt, 'CollectOutput', 1,'Delimiter',',','headerLines', 1, 'EmptyValue', 0);
I'm trying to handle it with the EmptyValue flag but it's not working. Any help is greatly appreciated.

I am not sure what exactly you mean by I'd like to import the string as it is in the data, or more exactly where you would like to have that string stored.
But about just reading your data as a whole you can use the 'TreatAsEmpty' argument:
d = textscan(fid, fmt, 'CollectOutput', 1,'Delimiter',',','headerLines', 1,'TreatAsEmpty','not enough samples');
Then you can modify the input further by looking for the rows in the imported data array that solely consist of zeros.

Related

How do I count all the characters in a string without dictionary/set/lists?

Write and develop a function getPartsInCode which has one string parameter: productCode. The function returns a string in this format:
if product code is AABBBGH, then the function returns 2A 3B 1G 1H.
I can't seem to find any that's similar to the output I want to get. The closest was
word = input("Enter a word: ")
Alphabet=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o'\
,'p','q','r','s','t','u','v','w','x','y','z']
for i in range(0,26):
if word.count(Alphabet[i]) > 0:
print(word.count(Alphabet[i]))
What I would do is create a dictionary that corresponds each letter to a specific integer value.
def get_parts_in_code(code): # Creating a function that takes one parameter: code
# Creating a dictionary called 'alphabet' that stores every letter and its corresponding value
alphabet = {
'A': 0,
'B': 0,
'C': 0,
'D': 0,
'E': 0,
'F': 0,
'G': 0,
'H': 0,
'I': 0,
'J': 0,
'K': 0,
'L': 0,
'M': 0,
'N': 0,
'O': 0,
'P': 0,
'Q': 0,
'R': 0,
'S': 0,
'T': 0,
'U': 0,
'V': 0,
'W': 0,
'X': 0,
'Y': 0,
'Z': 0,
'OTHER': 0, # An 'other' category for spaces, underscores, etc (anything that isn't in the english alphabet)
}
code = code.upper() # Making everything upercase
code = list(code) # Converting our code into a list
code.sort() # Sorting it alphebetically
for letter in code: # For every letter in our list (code)
try:
alphabet[letter] += 1 # It should try to increase the corresponding value by one
except:
alphabet['OTHER'] += 1 # If that failed, then it means that the charecter is not in our dictionary, so we instead increase the 'OTHER' value
for letter in alphabet: # For every letter in our dictionary (alphabet)
if alphabet[letter] > 0: # Instead of printing all the zeroes, let's only print the values greater than 0
print(letter, alphabet[letter]) # Print the letter and the corresponding values
get_parts_in_code("hello world") #Executing the function
In this code, we go through each item in the code and increase the dictionary value by one. In the end, we go through each value in our dictionary 'alphabet', and if the value is greater than zero, we print it. Read the comments for a line-by-line description of the code.

PostGIS conditional aggregration - presence/absence matrix

I have a dataset that resembles the following:
site_id, species
1, spp1
2, spp1
2, spp2
2, spp3
3, spp2
3, spp3
4, spp1
4, spp2
I want to create a table like this:
site_id, spp1, spp2, spp3, spp4
1, 1, 0, 0, 0
2, 1, 1, 1, 0
3, 0, 1, 1, 0
4, 1, 1, 0, 0
This question was asked here, however the issue I face is that my list of species is significantly greater and so creating a massive query listing each species manually would take a significant amount of time. I would therefore like a solution that does not require this and could instead read from the existing species list.
In addition, when playing with that query, the count() function would keep adding so I would end up with values greater than 1 where multiples of the same species were present in a site_id. Ideally I want a binary 1 or 0 output.

Swift: BLE 16 bytes to Int

I'm getting a byte array like this one:
[60, 2, 0, 0, 0]
In the documentation there is written this:
uint16 -> heartBeatNum;
uint8 -> rawDataFilesNum;
uint8 -> alertNum
uint8 -> fallsNum
I will explain a little about the device so that you understand and then I ask my question.
The bluetooth device sends an object every minute that is called heartbeat. If this is the first time the object is to use the array looks like this:
After first minute:
[1, 0, 0, 0, 0]
After two minute:
[2, 0, 0, 0, 0]
After three minute:
[3, 0, 0, 0, 0]
After for minute:
[4, 0, 0, 0, 0]
...
Now there are more than 12 that have passed and the array is:
[60, 2, 0, 0, 0]
So I try to understand from the documentation the heartbeat count is the first 16 bytes. I can not figure out how to collect the 60's and the 2's to have the exact heartbeat number.
How does this function?
According to my calculation if I do 60 * 12 = 720
So I should have about 700
Can someone enlighten me how to gather the 16 bytes in int?

Distribute elements evenly (adding ints values to array of int values)

Say I have an array of Ints and all elements equal zero. It'd look something like this:
let arr: [Int] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
There are 11 elements in this array in total. I want three of the elements in this array to be the number one. I want these one values to be distributed evenly throughout the array so that it looks something like this:
[0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0]
I want to be able to add however many one's and distribute them evenly (or as close to evenly as possible) no matter how many total elements there are. How could I do this?
Note: For anyone wondering why I need this, I have a collection of strings that when joined together make up a large body of text. Think of the zeroes as the pieces of text and think of the ones as advertisements I am adding in between the text. I wanted to distribute these ads as evenly as possible. I figured this would be a simple way of expressing what I needed.
Maybe you can try this.
var arr: [Int] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
let distribution = arr.count / 3 // 3 is the number of 1s
for (index, value) in arr.enumerated() {
arr[index] = (index + 1) % distribution == 0 ? 1 : value
}
print(arr) // [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0]
Assuming that the value distribution > 1

Postive/Negative Chart in Google Visualization API

I need to generate a chart like this one:
Specifically, I want to show both a positive value and a negative value for a time period (could be an hour, minute, etc.) and display it like this.
I could have sworn I saw something like this on the Google Visualization API Gallery the other day, but I can't find it now, and am not even sure what this kind of chart is called.
First, do you know what this kind of chart is called so I can possibly find documentation? Second, is there any way to implement such a chart with the Google Visualization API? If not, is there another common charting solution for web that I can achieve this with?
Thank you for your time.
This is called a "Stacked Bar Chart", and can indeed be created with the Google Visualisation API.
Simply use the "isStacked" property (described here; http://code.google.com/apis/visualization/documentation/gallery/barchart.html).
Here's some sample code (based off the default bar chart example provided by Google and updated to show the use of isStacked and some sample data from your example);
function drawVisualization() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Month');
data.addColumn('number');
data.addColumn('number');
data.addRows(12);
data.setCell(0, 0, 'January');
data.setCell(1, 0, 'February');
data.setCell(2, 0, 'March');
data.setCell(3, 0, 'April');
data.setCell(4, 0, 'May');
data.setCell(5, 0, 'June');
data.setCell(6, 0, 'July');
data.setCell(7, 0, 'August');
data.setCell(8, 0, 'September');
data.setCell(9, 0, 'October');
data.setCell(10, 0, 'November');
data.setCell(11, 0, 'December');
data.setCell(0, 1, 19);
data.setCell(1, 1, 18);
data.setCell(2, 1, 20);
data.setCell(3, 1, 19);
data.setCell(4, 1, 18);
data.setCell(5, 1, 20);
data.setCell(6, 1, 19);
data.setCell(7, 1, 18);
data.setCell(8, 1, 20);
data.setCell(9, 1, 19);
data.setCell(10, 1, 18);
data.setCell(11, 1, 20);
data.setCell(0, 2, -12);
data.setCell(1, 2, -13);
data.setCell(2, 2, -11);
data.setCell(3, 2, -12);
data.setCell(4, 2, -13);
data.setCell(5, 2, -11);
data.setCell(6, 2, -12);
data.setCell(7, 2, -13);
data.setCell(8, 2, -11);
data.setCell(9, 2, -12);
data.setCell(10, 2, -13);
data.setCell(11, 2, -11);
data.setCell(0, 2, -12);
data.setCell(1, 2, -13);
data.setCell(2, 2, -11);
// Create and draw the visualization.
new google.visualization.ColumnChart(document.getElementById('visualization')).
draw(data,
{title:"S&P 500 Up/Down Performance Since 1980",
width:600, height:400,
isStacked:"true",
legend:"none" }
);
}
And the results...
Use ColumnChart instead of BarChart:
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
https://jsfiddle.net/0rrar9oq/16