This does not seem possible, so my guess is I am thinking of how to handle my data incorrectly, not simply that I can't find a way to handle it the way I envision.
I wanted to create a 3-dimensional array; I am thinking of this like a relational database. All dimensions would have the same number of rows, but they have different number of columns.
For example,
dimension 1 = 1 column, 20 unique location identifiers (rows)
dimension 2 = 3 columns of abiotic variables associated with the 20 unique locations (rows)
dimension 3 = 2 columns of biotic variables associated with the 20 unique locations (rows)
I was thinking this would be the best way to set up my data so that I could go through each column easily and combine within abiotic or biotic easily just using subscripting (e.g., I could apply a function across all varibles (columns) in the 2nd (abiotic) dimension (e.g., dat[,,2] = log(dat[,,2]), which might be different than something I want to do to all biotic variables.
This is a not a treatment group type of analysis, so I don't want stacked data (where I repeat the unique locations 5 times with multiple treatment options for each location - that makes no sense to me for these data, e.g.,
loc type var
1 ab 1
1 ab 2
1 ab 3
1 bi 1
1 bi 2
I am frozen in the way I am thinking about these data. In the past I've always used arrays and the subscripting is so intuitive to me. Can you indeed make an array that has different number of columns in each dimension? If not, what am I missing about how to handle these data?
Thanks for any thoughts.
Yes. You can do as you are describing with
# build a 20 x 3 x 2 array
dat <- array(data, c(20,3,2))
# example of applying functions on a given dimension
log(dat[,,2])
There is no requirement that the dimensions of the array be equally sized.
Related
I have a transposed dynamic n x 2 array that is used to populate a combobox. The primary column alone is not descriptive enough to identify rows uniquely. I would like to use the row index to identify the untransposed column uniquely. Using both columns in the array could also be used for this but may prove problematic down the line. This question is closely related to this question.
I have used Me.cbo.ListIndex = 0 to retrieve the index value. Ideally, I'd like to assign the index of the row chosen in the combobox to a variable. The ultimate goal is to use the index in two ways:
For finding the correct column to use in future calculations
As a method for comparison against another combobox that uses the same array in order to ensure that the same row has not been chosen in both comboboxes
To visually illustrate the above, the original data looks like this:
a b c b
1 2 3 4
A B C B
The transposed array looks like this:
A 1
B 2
C 3
B 4
I would like to be able to make a distinction between selecting B2 and B4, ideally by preserving and comparing index 1 and 3 respectively (0-based).
ListIndex is from the documentation. There is no documentation that I could find about retrieving the index from the name except where the value in the selection is unique. Any Help is greatly appreciated
I have the following inputs
dataset 1 with tens of thousands of rows and 5 array columns
dataset 2 with tens of thousands of rows and 3 array columns
I want to join/merge (add) the 3th column of dataset 1 to a new 4th array column of dataset 2 for the elements for which the ID is the same (same value in column 1 of dataset 1 and column 1 of dataset 2). Mathematically you can write it like this I think:
dataset2(i,4)=dataset1(find(dataset1(:,1)==c(i,1)),3);
but how to put it in MATLAB?
None of the methods mentioned in the MATLAB help function or elsewhere on the internet seem to work. I have already tried merge, join, ismember, vectors, but I can't solve the problem.
Does someone have any ideas? I know the problem can be solved with for loops, but i'm not allowed to use them, so I am searching for alternatives.
I believe this is what you want
%We keep the index of all the matching rows
%NOTICE: I changed c(i,1) to dataset2(:,1)
%matches_in_col_1 = find(dataset1(:,1)==dataset2(:,1));
%EDIT: HOW TO COMPARE MORE THAN 2 COLUMNS
%if you want to find matches in 4 datasets just use this
matches_in_col_1 = find(dataset1(:,1)==dataset2(:,1)==dataset3(:,1)==dataset4(:,1));
%now copy the values from those rows into the corresponding row
%of datsaset2
dataset2(matches_in_col_1,4) = dataset1(matches_in_col_1,3);
I'm not 100% sure. Why is i present? were you trying a loop implementation? My solution also assumes that c was supposed to be dataset2
trying to do a formula only calculator and trying to avoid a bunch of nested ifs in "hidden" columns.
Basically this is a calculator for COC type of game.
So here is a rough table (not sure how to best make a table here):
A B K M
1 name current level Max Level Next level cost
6 Soldier 2 4 X
where x=IF($K6=B6,0,VLOOKUP($A6,Masterdata!$A$4:$CD$50,32+B6,0)))
the masterdata sheet is just the name some data across several columns, some more data across several columns, and then individual columns that contain a cost starting on column 32.
this works to find the cost of the next level (3) but I would like to do a sum with something like: IF($K6=B6,0,sum(VLOOKUP($A6,Masterdata!$A$4:$CD$50,{32+B6, 33+B6,34+b6},0)))). I can get the array to work if I put in fixed numbers ie, {35, 36, 37} but not {32+B6, 33+B6,34+b6}. Additionally, the array won't dynamically change. such as current level=1, max level=9 will require a larger array than current level =5 max, max level=9. Is there a way of doing this?
Further explanation of 2nd part:
example:
current level =1 max level =9
the formula would be something like: IF($K6=B6,0,sum(VLOOKUP($A6,Masterdata!$A$4:$CD$50,{32,33,34,35,36,37,38,39},0)))) I would require 8 columns in the array to be added.
But if current level is 6 and max level is 9 then it would look something like this:IF($K6=B6,0,sum(VLOOKUP($A6,Masterdata!$A$4:$CD$50,{37,38,39},0))))
I would only require 3 columns returned in the array to be added.
So even if the formula needs to remain IF($K6=B6,0,sum(VLOOKUP($A6,Masterdata!$A$4:$CD$50,{32,33,34,35,36,37,38,39},0)))) I would like to constrain the results to only columns 37,38,39
You should exclude the cell reference from the array of constants. And you will require SUMPRODUCT (or else SUM with CSE) to coerce an array of returns:
=IF($K6=B6,0,SUMPRODUCT(VLOOKUP($A6,Masterdata!$A$4:$CD$50,{32,33,34}+B6,0)))
I'm afraid I don't understand your second query re "the array won't dynamically change".
Regards
So I abandoned the vlookup and went the index match route:
Came up with: =SUM(INDEX(Masterdata!$A$1:$Z$32,MATCH($A26,Masterdata!$A$1:$A$32,0),B26+1+14):INDEX(Masterdata!$A$1:$Z$32,MATCH($A26,Masterdata!$A$1:$A$32,0),E26+14))
Seems to work great.
Basically I am finding the row number that matches my search criteria:MATCH($A26,Masterdata!$A$1:$A$32,0) = 26
I then enter that into an index with an offset of my first column based off my min value:index(range,26,B26+1+14), along with the max value:index(range,26,E26+14) and then sum them together sum(index1:index2)
I have a table in Excel:
A B C D
Day1 Day2 Day3
1 Ron 3 2 2
2 Don 4 2 1
3 Ton 1 5 2
On a different worksheet, I need to produce a table of the type (without using macros):
A B C D
Ron Don Ton
1 Ron - - -
2 Don 8 - -
3 Ton 10 11 -
Where the value is the MAX of each pairs value for each days, summed across all days. So if it was just for 3 names and days, I would just use the formula below with a VLOOKUP to see what the value for each name is on a particular day and copy/paste it for each day. (Side note, actually my project is not that big, so by the time I posted this question, I could have been done with it, but I really want to learn how to do this in a more intelligent way).
=SUM(MAX( VLOOKUP(Table2!$A2,Table1!$A:$D,2,FALSE), VLOOKUP(Table2!B$1,Table1!$A:$D,2,FALSE)), and so on Day2, Day3...
I tried the following:
{=SUM(MAX(VLOOKUP(Table2!$A2,Table1!$A:$D,{2,3,4},FALSE),VLOOKUP(Table2!D$1,Table1!$A:$D,{2,3,4},FALSE)))}
However, apparently the VLOOKUP can't return an array (and INDEX MATCH can't either).
Any help would be much appreciated.
L42 is right - VLOOKUP has trouble returning an array when the lookup value is a range or array but with an array in place of column index number it returns an array no problem
To see that just put a single VLOOKUP in a cell, e.g.
=VLOOKUP($A2,Table1!$A:$D,{2,3,4},0)
then select the cell, press F2 to select the formula and F9 to see the result and you get a result like ={3,2,2}
The problem with your formulas is that MAX just takes the largest value of the six values returned by the two VLOOKUPs, it doesn't compare the two arrays
To do that in a single formula you can use a formula of the following form:
=SUM(IF(array1>array2,array1,array2))
that will compare the 2 arrays and sum the largest value in each position, for your setup that would be a formula like this in Table2 B2
=IF($A2=B$1,"-",SUM(IF(VLOOKUP($A2,Table1!$A:$D,{2,3,4},0)>VLOOKUP(B$1,Table1!$A:$D,{2,3,4},0),VLOOKUP($A2,Table1!$A:$D,{2,3,4},0),VLOOKUP(B$1,Table1!$A:$D,{2,3,4},0))))
confirm with CTRL+SHIFT+ENTER and copy across and down
If you have a larger number of columns then to avoid using {2,3,4,5,6,7,8,9,10......etc.} you can use INDEX/MATCH instead of VLOOKUP like this
=INDEX(Table1!$B:$D,MATCH($A2,Table1!$A:$A,0),0)
Note: INDEX here is returning a range (not an array). The MATCH function determines the row number and a zero as the column argument means you get the whole row returned
I'm sifting through a data set, and grouping certain rows together. The data set is 18 rows by 8 columns. It contains both numerical and word info. My method is as follows: If the first 5 columns of a row are the same as another row, I want group those two rows together in a matrix.
Here is my my issue:
I do not know how many rows will be the same (therefore, when I create a matrix of the rows I won't know its dimensions). I have concluded that I need an array that can store different sized matrices. Is this possible? If not, how would you recommend I store the rows?
Thanks!