i have this type of table. which is in the below image.
Age Height Weight Smoker SelfAssessedHealthStatus
___ ______ ______ ______ ________________________
Smith 38 71 176 true Excellent
Johnson 43 69 163 false Fair
Williams 38 64 131 false Good
Jones 40 67 133 false Fair
Brown 49 64 119 false Good
Davis 46 68 142 false Good
Miller 33 64 142 true Good
Wilson 40 68 180 false Good
Moore 28 68 183 false Excellent
now I need only the row where "Good". this type of data is available in last column.
please help. I am new to MATLAB.
I've prepared a similar xlsx-file and next read it with readtable function
T = readtable('test.xlsx','ReadVariableNames',false)
Then you can make logical array with detecting rows you need:
idx = ismember(T.Var5,'LBNP:30')
And next just select these rows:
T(idx,:)
Related
I have a table:
t:([]val:10?100)
And I want to add a column with a cond statement: If value is below 55, just set it to 55. However the update statement does not work with that:
update newVal:$[val<55;55;val] from
How do I have to change it?
Thanks.
Since val is a vector you have to use the vector conditional
update newVal:?[val<55;55;val] from t
By the way, an alternative way of flooring it out at 55 is to use max/or (|)
update val|55 from t
I think #terrylynch is perfect. But sometimes when vector condition is too hard to use, you can use a lambda inside q-sql statement as well. And for the reason for using vector condition is simply because a column is a list
q)t
val
---
12
10
1
90
73
90
43
90
84
63
q)update newVal:{$[x<55;55;x]}each val from t
val newVal
----------
12 55
10 55
1 55
90 90
73 73
90 90
43 55
90 90
84 84
63 63
q)update newVal:{x|55}each val from t
val newVal
----------
12 55
10 55
1 55
90 90
73 73
90 90
43 55
90 90
84 84
63 63
I'm trying to eliminate duplicate entries for customers in my contact list. Assume my table has three columns (FirstName, LastName, CustomerID).
Can somebody help me create a query that identifies different CustomerIDs with either the same or very similar First and Last Names? We end up with multiple entries due to sales people searching for a name and not finding it due to misspellings. They then create a new entry for the customer with a slightly different spelling of the name.
Thanks!
One approach is to manage a mapping of names to common (mis)spellings and then map all the various spellings back to the intended name. Then group them.
t:([] fn:100?(`John;`Mike;`Bob;`john;`Johnn;`Mick;`Bobby);ln:100?(`Doe;`Smith;`doe;`Do;`smith);id:til 100)
mapFN:exec similar!name from ungroup flip `name`similar!flip (
(`Bob; (`Bob;`bob;`Bobby;`bobby));
(`John; (`John;`Johnn;`john));
(`Mike; (`Mike;`mike;`Mick;`Michael))
);
mapLN:exec similar!name from ungroup flip `name`similar!flip (
(`Doe; (`Doe;`doe;`Do));
(`Smith; (`Smith;`smith;`Smyth))
);
Without mapping:
q)`fn`ln xgroup t
fn ln | id
-----------| ----------------
Mick Do | 0 25 26 50 68 71
Bobby Smith| 1 22 23 83
John Smith| 2 8 48 51 69 85
Mike Doe | 3 44
john doe | ,4
Mick Doe | 5 47 95
John Doe | 6 46 49 63
john Smith| 7 66 74
Johnn doe | 9 13 79 94
Mick doe | 10 20 55 67
Bobby smith| 11 17 18 53
john Doe | 12 21 56
...
With mapping:
q)`fn`ln xgroup update mapFN[fn],mapLN[ln] from t
fn ln | id
----------| -----------------------------------------------------------------
Mike Doe | 0 3 5 10 20 25 26 39 44 47 50 52 55 67 68 70 71 78 95 97
Bob Smith| 1 11 17 18 22 23 30 38 45 53 77 82 83
John Smith| 2 7 8 16 19 33 37 40 43 48 51 64 66 69 73 74 80 85 87
John Doe | 4 6 9 12 13 21 31 32 41 42 46 49 56 57 62 63 65 72 79 81 86 89 91
Bob Doe | 14 24 27 28 35 54 58 59 61 75 76 84
Mike Smith| 15 29 34 36 60 88 90 93 96 98
You could also do something more sophisticated with regex pattern matching.
The mapping would need to be pretty precise though as otherwise you might end up with false groupings
I have a matrix A
A=[f magic(10)]
A=
931142103 92 99 1 8 15 67 74 51 58 40
931142103 98 80 7 14 16 73 55 57 64 41
931142103 4 81 88 20 22 54 56 63 70 47
459200101 85 87 19 21 3 60 62 69 71 28
459200101 86 93 25 2 9 61 68 75 52 34
459200101 17 24 76 83 90 42 49 26 33 65
459200101 23 5 82 89 91 48 30 32 39 66
37833100 79 6 13 95 97 29 31 38 45 72
37833100 10 12 94 96 78 35 37 44 46 53
37833100 11 18 100 77 84 36 43 50 27 59
The first column are firm codes. The rest columns are firms' data, with each row referring to the firm in Column 1 in a given year. Notice that years may not be balance for every firms.
I would like to subtract sub-matrices according to the first column. For instance, for A(1:3,2:11) for 931142103:
A(1:3,2:11)
ans =
92 99 1 8 15 67 74 51 58 40
98 80 7 14 16 73 55 57 64 41
4 81 88 20 22 54 56 63 70 47
Same as 459200101 (which would be A(4:7,2:11)) and A(8:10,2:11) for 37833100.
I get a sense that the code should like this:
indices=find(A(:,1));
obs=size(A(:,1));
for i=1:obs,
if i==indices(i ??)
A{i}=A(??,2:11);
end
end
I have difficulties in indexing these complicated codes: 459200101 and 37833100 in order to gather them together. And how can I write the rows of my submatrix A{i}?
Thanks so much!
One approach with arrayfun -
%// Get unique entries from first column of A and keep the order
%// with 'stable' option i.e. don't sort
unqA1 = unique(A(:,1),'stable')
%// Use arrayfun to select each such submatrix and store as a cell
%// in a cell array, which is the final output
outA = arrayfun(#(n) A(A(:,1)==unqA1(n),:),1:numel(unqA1),'Uni',0)
Or this -
[~,~,row_idx] = unique(A(:,1),'stable')
outA = arrayfun(#(n) A(row_idx==n,:),1:max(row_idx),'Uni',0)
Finally, you can verify results with a call to celldisp(outA)
If values in column 1 always appear grouped (as in your example), you can use mat2cell as follows:
result = mat2cell(A, diff([0; find(diff(A(:,1))); size(A,1)]));
If they don't, just sort the rows of A according to column 1 before applying the above:
A = sortrows(A,1);
result = mat2cell(A, diff([0; find(diff(A(:,1))); size(A,1)]));
If you don't mind the results internally not being ordered, you can use accumarray for this:
[~,~,I] = unique(A(:,1),'stable');
partitions = accumarray(I, 1:size(A,1), [], #(I){A(I,2:end)});
Chemical composition of a certain material
Hi,
I am trying to import the below mentioned data in CSV format in matlab, which is [1000x10] in dimensions.
HCL;H2SO4;CH4; SULPHUR;CHLORINE;S2O3;SO2;NH3;CO2;O2
144 2 3 141 140 6 7 137 136 10 11 133
13 131 130 16 17 127 126 20 21 123 122 24
25 119 118 28 29 115 114 32 33 111 110 36
108 38 39 105 104 42 43 101 100 46 47 97
96 50 51 93 92 54 55 89 88 58 59 85
61 83 82 64 65 79 78 68 69 75 74 72
73 71 70 76 77 67 66 80 81 63 62 84
60 86 87 57 56 90 91 53 52 94 95 49
48 98 99 45 44 102 103 41 40 106 107 37
109 35 34 112 113 31 30 116 117 27 26 120
121 23 22 124 125 19 18 128 129 15 14 132
12 134 135 9 8 138 139 5 4 142 143 1
I am able to import this data through my code
fid = fopen(uigetfile('.csv'),'rt');
FileName = fopen(fid);
headers = fgets(fid); %get first line
headers = textscan(headers,'%s','delimiter',';'); %read first line
format = repmat('%f',1,size(headers{1,1},1)); %count columns n makeformat string
data = textscan(fid,format,'delimiter',';'); %read rest of the file
data = [data{:}];
I am getting data in matrix form in variable data [1000x10] and name of all the components like HCL, H2SO4 in a cell array named headers{1x1}.
Now I have two questions like the built in import feature in matlab you have flexibility to import data as separate column vectors, numeric matrix,cell array and table format. Is it possible to do as such through code, like i get column vectors with their name HCL with [1000x1] and H2sO4 with [1000x1] in my workspace after import and so on all the column vectors with their names with [1000x1]dimensions.
if yes then help me please...?
If above mentioned is not possible then i can do alternatively that now I have names of column vectors in headers cell array, how I can extract those name and use those names as column vector names through code and I can assign data from data matrix [1000x10] to each column vector with their corresponding names.
like if i say
x = headers {1*1}{1*1}; i will get x = "HCL"
x = genvarname(x); I will get x= x0x22HCL0x2 BUT
I want that x get replaced with HCL.and then I assign
HCL = data(:,1) and same like this other variables H2SO4,SULPHUR, CHLORINE.
You can say i try to implement the import feature of column vector through my code.
Kindly help me to solve this issue. thanks
Have you tried the built-in readtable function?
You can access each column of the table by using the named column header.
If you'd like, you can use the two data types to create a table in MatLab. I'm not terribly familiar with its use, but it seems to be well documented. I'm sure someone else can expand upon this.
Edit:
After re-reading your question, I think this is closer to what you are after.
n=10;
what='HCL';%change this to any of the strings you interested in
numstr = repmat('%f',1,n);
hdrstr = repmat('%s',1,n);
headers = textscan(headers,hdrstr,'delimiter',';');
headers = headers(1,:)
data = cell2mat(textscan(fid,numstr,'delimiter',';'));
datout = data(:,strcmp(headers,what));%datout will be 1000x1 HCL data
Depending on what you want to do, you can loop through these appropriately
I know this is not what you asked for, but I would convert to a struct:
x=cell2struct(num2cell(data),headers,2)
reason is simple, selecting for example the third row with individual variables is not possible. With a struct simply use x(3)
If at some point you need the vectors you originally asked for and you can't use the strcut, use [x.HCL]
I have a crosstab that prints data like this
univNr tst1 tst2 reslt prak dnp
123 45 75 Pass 51 60
124 32 40 Fail 39 45
125 81 85 Dist 90 79
126 49 70 Pass 53 62
127 60 65 Pass 53 69
How do I add a averages column at the bottom so that it looks like this
univNr tst1 tst2 reslt prak dnp
123 45 75 Pass 51 60
124 32 40 Fail 39 45
125 81 85 Dist 90 79
126 49 70 Pass 53 62
127 60 65 Pass 52 69
Average: 53 67 57 63
Extra Info:
I'm using iReport 5.5 to create reports for JasperReports Server 5.0.1
The data given to the crosstab to pivot looks something like this
univNr module modVal
123 tst1 45
123 tst2 75
123 result Pass
123 prak 51
123 dnp 60
124 tst1 32
124 tst2 45
124 result Fail
124 prak 39
124 dnp 45
I've Tried many solutions and spoken to jasper support, it Appears there is no Way to do this since You can't work out the average of a string field.
What I ended up doing is modifying the Query to put all the string values of "modVal" in a separate column "result" so that I can make "modVal" and Int, and then be able to work out the averages / totals