Reputation: 1
I am working in program r and need help with writing some code. I have a 50 by 3 by 8 dimensional array. Most cells in this array are zero, but some are NA. I need to replace the zeroes in the array with a sequence of numbers such that all cells in a row have the same number. The sequence starts at 1 and runs to total number of rows in the array. Also, the NAs must remain, so cells with NAs cannot be overwritten. Further, some rows are all NAs and so the row sequence will not be exactly 400 (50 x 8), but something less. I have found information on how to address each part of this problem, but am struggling to put all the pieces together in a way that works. I greatly appreciate your help writing this r code.
Example, for this array:
y<-array(0,dim=c(10,3,2))
#add NAs
y[4,2:3,1]<-NA
y[8,1:3,1]<-NA
y[10,1:3,2]<-NA
I need to replace the 0's with a sequence such that the first matrix in the array has its rows numbered 1 to 9 (all cells in row 1=1, 2=2, and so on, with NAs left in place). Matrix 2 would have rows numbered 10 to 18.
Upvotes: 0
Views: 589
Reputation: 145775
As far as I can tell, this is what you want (on a small scale for illustration).
## Set up example data
## (you should provide something like this in your question!!)
set.seed(47)
d = c(5, 2, 3)
x = array(sample(c(0, NA), size = prod(d), replace = T), dim = d)
# set a row to all na:
x[2, , ] = NA
We first find the rows that are not all NA
, and calculate the replacement sequence. Then we do the replacing in a simple for
loop.
r = ! apply(is.na(x), MARGIN = 1, all)
rows = which(r)
rn = seq_along(r[r])
for (i in seq_along(rows)) {
x[rows[i], , ][x[rows[i], , ] == 0] = rn[i]
}
x
# , , 1
#
# [,1] [,2]
# [1,] NA NA
# [2,] NA NA
# [3,] NA 2
# [4,] NA NA
# [5,] NA NA
#
# , , 2
#
# [,1] [,2]
# [1,] 1 NA
# [2,] NA NA
# [3,] 2 2
# [4,] NA 3
# [5,] NA 4
#
# , , 3
#
# [,1] [,2]
# [1,] 1 1
# [2,] NA NA
# [3,] NA 2
# [4,] 3 NA
# [5,] NA NA
If this isn't what you want, please clarify your question providing sample input and corresponding desired output.
Addressing edits to question, two more methods: an ugly understandable way and an entirely too clever way:
# sample data
set.seed(47)
d = c(5, 2, 3)
x = array(sample(c(0, NA), size = prod(d), replace = T), dim = d)
# nested for loopsr
r = !apply(is.na(x), c(1, 3), all)
counter = 0
for (k in 1:dim(x)[3]) {
for (i in 1:dim(x)[1]) {
if(r[i, k]) {
counter = counter + 1
x[i, , k] = x[i, , k] + counter
}
}
}
x
# now the clever way
# reset the data
set.seed(47)
x = array(sample(c(0, NA), size = prod(d), replace = T), dim = d)
xm = matrix(aperm(x, c(1, 3, 2)), ncol = 2)
axm = ! apply(is.na(xm), 1, all)
xm = xm + cumsum(axm)
aperm(array(c(xm), dim = d[c(1, 3, 2)]), c(1, 3, 2))
# , , 1
#
# [,1] [,2]
# [1,] NA NA
# [2,] 1 1
# [3,] NA 2
# [4,] NA NA
# [5,] NA NA
#
# , , 2
#
# [,1] [,2]
# [1,] 3 NA
# [2,] NA 4
# [3,] 5 5
# [4,] NA 6
# [5,] NA 7
#
# , , 3
#
# [,1] [,2]
# [1,] 8 8
# [2,] NA 9
# [3,] NA 10
# [4,] 11 NA
# [5,] NA NA
Upvotes: 1