Related
I am doing a metanalysis of proportions using the metafor package and the rma.glmm function.
Since I the dataset is large, with many variables, I would like to reiterate the rma.glmm function through some columns of the dataframe.
This is the dataframe:
dput(data)
structure(list(event = c(5, 55, 4, 43, 2, 45, 34, 0, 34, 2, 23,
54, 45, 45, 67, 67, 78, 34, 45, 0, 34, 2, 23, 54, 45, 45, 67,
67, 78, 34, 45, 0, 34, 2, 23, 54, 45, 45), tot = c(45, 67, 89,
111, 133, 155, 177, 199, 221, 243, 265, 287, 309, 331, 353, 375,
397, 419, 441, 463, 485, 507, 529, 551, 573, 595, 617, 639, 661,
683, 705, 727, 749, 771, 793, 815, 837, 859), moderator = c("a",
"a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a",
"a", "a", "a", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b",
"b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b"), x1 = c(5,
55, 4, 43, 2, 45, 34, 0, 34, 2, 23, 54, 45, 45, 67, 67, 78, 34,
45, 0, 34, 2, 23, 54, 45, 45, 67, 67, 78, 34, 45, 0, 34, 2, 23,
54, 45, 45), x2 = c(6, 56, 5, 44, 3, 46, 35, 1, 35, 3, 24, 55,
46, 46, 68, 68, 79, 35, 46, 1, 35, 3, 24, 55, 46, 46, 68, 68,
79, 35, 46, 1, 35, 3, 24, 55, 46, 46), x3 = c(7, 57, 6, 45, 4,
47, 36, 2, 36, 4, 25, 56, 47, 47, 55, 4, 43, 2, 45, 34, 0, 34,
2, 23, 54, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45
)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA,
-38L))
And I wrote the following code:
columns <- c(4,5,6) # I decide which columns of the dataframe I want analyze
n_columns <- as.numeric(length(columns))
for (var in 1:n_columns){
colname <- colnames(data[,columns[var]])
glmm<-rma.glmm(xi=colname, ni=tot, measure="PLO", data=data)
pes=predict(glmm, transf=transf.ilogit, targ=list(ni=data$tot))
}
I get the following error:
Error in ni - xi : non-numeric argument to binary operator
Basically, the code does not read the variable name which is assigned to colname.
Can anyone help? Thank you
colname is a string, which doesn't work. It's a bit like you are trying to do something like lm("x1" ~ x2, data=data).
You can simply use
glmm <- rma.glmm(xi=data[[var]], ni=tot, measure="PLO", data=data)
And you can leave out the targ=list(ni=data$tot) from predict(). This has no effect.
I have a double array where I need to search the first row using a jtextfield input to get the index (position of [i]), then use that index number to identify the second row location and use the variable in the second array row. I'm using this to get the Gross Profit Margin Multiplier in second row of the array based on the position of the percentage margin in the first row array.
Do appreciate your help. I have searched other array links but they deal ether with the locations and not the contents of the locations.
public void getMarginArray(){
double[][] margn = {{10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50},
{1.11, 1.12, 1.13, 1.15, 1.16, 1.17, 1.19, 1.20, 1.22, 1.23, 1.25, 1.26, 1.28, 1.30, 1.31, 1.33, 1.35, 1.37, 1.39, 1.41, 1.43, 1.45, 1.47, 1.49, 1.51, 1.55, 1.56, 1.59, 1.61, 1.64, 1.67, 1.70, 1.72, 1.75, 1.79, 1.82, 1.86, 1.89, 1.92, 1.96, 2.00}};
Double MARG = Double.parseDouble( jtxtfldMargin.getText());
Double MAR1;
for (int i=0; i<margn.length; i++){
if (margn[0][i] ==MARG){
Double MAR1=margn[1][i];
System.out.println(margn[0][i]);
System.out.println(margn[1][i]);
System.out.println(MAR1);
};
};
I was able to get what I needed by changing to two separate arrays. Now when the first array matches the text field, the location is used for the second array to get the multiplier:
public void getMarginArray(){
double[] doubleArray1 = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50};
double[] doubleArray2 = {1.11, 1.12, 1.13, 1.15, 1.16, 1.17, 1.19, 1.20, 1.22, 1.23, 1.25, 1.26, 1.28, 1.30, 1.31, 1.33, 1.35, 1.37, 1.39, 1.41, 1.43, 1.45, 1.47, 1.49, 1.51, 1.55, 1.56, 1.59, 1.61, 1.64, 1.67, 1.70, 1.72, 1.75, 1.79, 1.82, 1.86, 1.89, 1.92, 1.96, 2.00};
Double MARG = Double.parseDouble( jtxtfldMargin.getText());
Double margMult;
for(int i = 0; i<doubleArray1.length; i++){
for(int j = 0; j<doubleArray2.length;j++){
if(doubleArray1[i] == MARG ){
margMult = doubleArray2[i];
System.out.println(margMult);
}
}
}
}
I have a list of arrays, in which each array represents a cell and the array elements are the coordinates x,y and z, the time point and the cell id. Here a sector of it:
cells=[ ...,
[ 264.847, 121.056, 30.868, 42. , 375. ],
[ 259.24 , 116.875, 29.973, 43. , 375. ],
[ 260.757, 118.574, 32.772, 44. , 375. ]]), array([[ 263.967, 154.089, 55.5 , 38. , 376. ],
[ 260.744, 152.924, 55.5 , 39. , 376. ],
[ 258.456, 151.373, 55.5 , 40. , 376. ],
...,
[ 259.086, 159.564, 48.521, 53. , 376. ],
[ 258.933, 159.796, 48.425, 54. , 376. ],
[ 259.621, 158.719, 51.606, 55. , 376. ]]), array([[ 291.647, 57.582, 28.178, 38. , 377. ],
[ 284.625, 59.221, 30.028, 39. , 377. ],
[ 282.915, 59.37 , 30.402, 40. , 377. ],
...,
[ 271.224, 58.534, 23.166, 42. , 377. ],
[ 270.048, 58.738, 21.749, 43. , 377. ],
[ 268.38 , 58.138, 20.606, 44. , 377. ]]), array([[ 87.83 , 222.144, 26.258, 39. , 378. ],
[ 99.779, 223.631, 24.98 , 40. , 378. ],
[ 104.107, 224.177, 23.728, 41. , 378. ],
...,
[ 127.778, 222.205, 23.123, 63. , 378. ],
[ 126.815, 222.347, 23.934, 64. , 378. ],
[ 127.824, 221.048, 25.508, 65. , 378. ]]),...]
minimumCellCoors = cells
maximumCellCoors = cells
centoEdge = radius+fcr_size
Now i want to change the coordinates x, y and z, so the 0.,1. and 2. element of the arrays in the list to get them in a specific grid. The user gives the spacing for x,y and z and then the operation could look like:
x_Coo=round(x_element/x)*x
y_Coo=round(y_element/y)*y
z_Coo=round(z_element/z)*z
So the real question here is, how could i do a operation on all of the elements in the array ( or in this case the first three elements in the array in the list)?
EDIT
If i use list comprehension to the list like:
[np.round((cellID[:,0]-(centoEdge+1))/x)*x for cellID in minimumCellCoors]
[np.round((cellID[:,1]-(centoEdge+1))/y)*y for cellID in minimumCellCoors]
[np.round((cellID[:,2]-(centoEdge+1))/z)*z for cellID in minimumCellCoors]
[np.round((cellID[:,0]+(centoEdge+1))/x)*x for cellID in maximumCellCoors]
[np.round((cellID[:,1]+(centoEdge+1))/x)*y for cellID in maximumCellCoors]
[np.round((cellID[:,2]+(centoEdge+1))/x)*z for cellID in maximumCellCoors]
How could i fusion the single lists of arrays to one array again?
Best regards!
First off you need to convert your list to a numpy array. It's more proper to create a numpy array instead of a list at first place. Then you can take advantage of numpy's vectorized operation support:
Here is an example:
In [45]: arr = np.arange(100).reshape(4, 5, 5)
In [46]: arr
Out[46]:
array([[[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19],
[20, 21, 22, 23, 24]],
[[25, 26, 27, 28, 29],
[30, 31, 32, 33, 34],
[35, 36, 37, 38, 39],
[40, 41, 42, 43, 44],
[45, 46, 47, 48, 49]],
[[50, 51, 52, 53, 54],
[55, 56, 57, 58, 59],
[60, 61, 62, 63, 64],
[65, 66, 67, 68, 69],
[70, 71, 72, 73, 74]],
[[75, 76, 77, 78, 79],
[80, 81, 82, 83, 84],
[85, 86, 87, 88, 89],
[90, 91, 92, 93, 94],
[95, 96, 97, 98, 99]]])
In [51]: arr[:,:,:3] = np.round(arr[:,:,:3]/5)*5
In [52]: arr
Out[52]:
array([[[ 0, 0, 0, 3, 4],
[ 5, 5, 5, 8, 9],
[10, 10, 10, 13, 14],
[15, 15, 15, 18, 19],
[20, 20, 20, 23, 24]],
[[25, 25, 25, 28, 29],
[30, 30, 30, 33, 34],
[35, 35, 35, 38, 39],
[40, 40, 40, 43, 44],
[45, 45, 45, 48, 49]],
[[50, 50, 50, 53, 54],
[55, 55, 55, 58, 59],
[60, 60, 60, 63, 64],
[65, 65, 65, 68, 69],
[70, 70, 70, 73, 74]],
[[75, 75, 75, 78, 79],
[80, 80, 80, 83, 84],
[85, 85, 85, 88, 89],
[90, 90, 90, 93, 94],
[95, 95, 95, 98, 99]]])
Note that you can also perform the operations with same length arrays as well as scalars:
For instance you could also do the following:
In [53]: arr[:,:,:3] = np.round(arr[:,:,:3]/5)*[4, 5, 6]
I have a two-dimensional array with sub-arrays of equal size, for example:
array = [
[10, 12, 15 ,17], [16, 32, 65, 47], [45, 48, 41, 23],
[36, 25, 74, 98], [32, 19, 66, 88]
]
I would like to create a new array by summing the corresponding elements of every 4th sub-array, i.e. the elements that are "on top of each other" in the above example:
new_array = [
[10 + 36, 12 + 25, 15 + 74, 17 + 98],
[16 + 32, 32 + 19, 65 + 66, 47 + 88],
[45, 48, 41, 23]
]
These are just examples, the actual arrays can be larger.
Complete Matrix
You can use each_slice, transpose, map and transpose again to navigate your matrix.
The code first uses join('+') to show what is being calculated :
array= [[10,12,15,17],[16,32,65,47],[45,48,41,23],[36,25,74,98],[32,19,66,88],[1,2,3,4]]
array.each_slice(3).to_a.transpose.map{|r| r.transpose.map{|x| x.join('+')}}
# => [["10+36", "12+25", "15+74", "17+98"], ["16+32", "32+19", "65+66", "47+88"], ["45+1", "48+2", "41+3", "23+4"]]
array.each_slice(3).to_a.transpose.map{|r| r.transpose.map{|x| x.inject(:+)}}
# => [[46, 37, 89, 115], [48, 51, 131, 135], [46, 50, 44, 27]]
Warning!
You need to carefully select the each_slice parameter to suit your original array. transpose might raise an exception otherwise :
array = [[10,12,15,17],[19,32,65,47],[45,48,41,23],[36,25,74,98],[10,12,15,17],[16,98,65,47],[69,48,65,23],[66,25,74,98]]
array.each_slice(3).to_a.transpose.map{|r| r.transpose.map{|x| x.inject(:+)}}
#=> IndexError: element size differs (2 should be 3)
array.each_slice(4).to_a.transpose.map{|r| r.transpose.map{|x| x.inject(:+)}}
#=> [[20, 24, 30, 34], [35, 130, 130, 94], [114, 96, 106, 46], [102, 50, 148, 196]]
Incomplete Matrix
If the matrix size isn't a multiple of width :
array = [
[10, 12, 15 ,17], [16, 32, 65, 47], [45, 48, 41, 23],
[36, 25, 74, 98], [32, 19, 66, 88]
]
you could add subarrays full of 0s to get :
matrix = [
[10, 12, 15 ,17], [16, 32, 65, 47], [45, 48, 41, 23],
[36, 25, 74, 98], [32, 19, 66, 88], [ 0, 0, 0, 0]
]
Array#fill does the job :
def maxtrix_column_sums(array, width)
size = array.size
size2 = array.first.size
missing = (-size) % width
matrix = array.dup.fill(Array.new(size2, 0), size...size + missing)
matrix.each_slice(width).to_a.transpose.map { |r| r.transpose.map { |x| x.join('+') } }
end
p maxtrix_column_sums(array, 3)
#=> [["10+36", "12+25", "15+74", "17+98"], ["16+32", "32+19", "65+66", "47+88"], ["45+0", "48+0", "41+0", "23+0"]]
Here's a variation of Eric Duminil's answer using zip instead of transpose to account for an "odd" number of sub-arrays:
first, *rest = array.each_slice(3).to_a
first.zip(*rest).map { |r| r.compact.transpose.map { |x| x.inject(:+) } }
#=> [[46, 37, 89, 115], [48, 51, 131, 135], [45, 48, 41, 23]]
How it works:
each_slice separates the array into groups of 3:
array.each_slice(3).to_a
#=> [
# [[10, 12, 15, 17], [16, 32, 65, 47], [45, 48, 41, 23]],
# [[36, 25, 74, 98], [32, 19, 66, 88]]
# ]
first.zip(*rest) combines the first slice "column"-wise with the remaining slices, adding nil when a slice is missing:
first.zip(*rest)
#=> [
# [[10, 12, 15, 17], [36, 25, 74, 98]],
# [[16, 32, 65, 47], [32, 19, 66, 88]],
# [[45, 48, 41, 23], nil]
# ]
The map / compact / transpose part then restructures the sub-array while getting rid of nil values:
first.zip(*rest).map { |r| r.compact.transpose }
#=> [
# [[10, 36], [12, 25], [15, 74], [17, 98]],
# [[16, 32], [32, 19], [65, 66], [47, 88]],
# [[45], [48], [41], [23]]
# ]
And inject(:+) finally sums the inner elements.
I've currently got a string array and I want to convert this to a UInt8 array? All of the strings are UInt8's, however I can only retrieve it as a string. Any ideas?
let stringValues = "[185, 221, 199, 111, 152, 137, 41, 137, 223, 66, 75, 132]"
I have each item in the array split up into its individual part, I just don't know how to convert the string to UInt8.
Thanks
This works:
var stringValues = "[185, 221, 199, 111, 152, 137, 41, 137, 223, 66, 75, 132]"
stringValues = stringValues.stringByReplacingOccurrencesOfString("[", withString: "").stringByReplacingOccurrencesOfString("]", withString: "").stringByReplacingOccurrencesOfString(" ", withString: "")
var values = [UInt8]()
print(stringValues)
for item in stringValues.componentsSeparatedByString(",") {
if let value = UInt8(item) {
values.append(value)
}
}
let stringValues = "[185, 221, 199, 111, 152, 137, 41, 137, 223, 66, 75, 132]"
let uint8Values = stringValues.componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString:" ,\"[]"))
.filter { !$0.isEmpty}.flatMap{ UInt8($0) }
Try this one
For single String conversion to UInt8
let unt = UInt8("231")
or you can use complete array as array of UInt8.
let stringValues :[UInt8] = [185, 221, 199, 111, 152, 137, 41, 137, 223, 66, 75, 132]