I have coding of a function in R as following:
matching_score=function(nitems, tot.score) {
nInterval <- 4*nitems+1
tot <- array(0, dim=c(nInterval,2,nGroup.all) )
minimum <- nitems
maximum <- nitems*5
tot[,1,] <- c(minimum: maximum)
for (nGcut in 1:nGroup.all)
{
...
But R gave an error message as :
Error in tot[, 1, ] <- c(minimum:maximum) :
incorrect number of subscripts
How can I solve this issue? When minimum and maximum were actual numbers, the error was not presented.
Thanks in advance for your advice.
The error probably occurs when you try to cbind the tot object. The error message is complaining about dimensions. You are using "[" as if this object is an array with three dimensions and 'cbind' will not work with arrays. If it's really a three dimensional object the install package 'abind' and use function abind.
require(abind)
arr <- array(1:(2*3*4), c(4,3,2) )
abind(arr, arr[,,1], along=3)
The dimensions of this line:
tempo[nRw,] <- cbind(tot[nRw,1,1], sum(tot[nRw,2,]))
... seem all wrong. The LHS has two dimensions, the 'tot' object has three and the return from sum will be a scalar.
Related
I am applying a user-defined function to individual cells of a 3D array. The contents of each cell are one of the following possibilities, all of which are character vectors because of prior formatting:
"N"
"A"
""
"1"
"0"
I want to create a new 3D array of the same dimensions, where cells contain either NA or a numeric vector containing 1 or 0. Thus, I wrote a function named Numericize and used aaply to apply it to the entire array. However, it takes forever to apply it.
Numericize <- function(x){
if(!is.na(x)){
x[x=="N"] <- NA; x
x[x=="A"] <- NA; x
x[x==""] <- NA; x
x <- as.integer(x)
}
return(x)
}
The dimensions original array are 480x866x366. The function takes forever to apply using the following code:
Final.Daily.Array <- aaply(.data = Complete.Daily.Array,
.margins = c(1,2,3),
.fun = Numericize,
.progress = "text")
I am unsure if the speed issue comes from an inefficient Numericize, an inefficient aaply, or something else entirely. I considered trying to set up parallel computing using the plyr package but I wouldn't think that such a simple command would require parallel processing.
On one hand I am concerned that I created a stack overflow for myself (see this for more), but I have applied other functions to similar arrays without problems.
ex.array <- array(dim = c(3,3,3))
ex.array[,,1] <- c("N","A","","1","0","N","A","","1")
ex.array[,,2] <- c("0","N","A","","1","0","N","A","")
ex.array[,,3] <- c("1","0","N","A","","1","0","N","A")
desired.array <- array(dim = c(3,3,3))
desired.array[,,1] <- c(NA,NA,NA,1,0,NA,NA,NA,1)
desired.array[,,2] <- c(0,NA,NA,NA,1,0,NA,NA,NA)
desired.array[,,3] <- c(1,0,NA,NA,NA,1,0,NA,NA)
ex.array
desired.array
Any suggestions?
You can just use a vectorized approach:
ex.array[ex.array %in% c("", "N", "A")] <- NA
storage.mode(ex.array) <- "integer"
You can simply use the second line and it will introduce NAs by coercion.
I have created a 3D-array and want to fill it with data from two other data.frames
Those data.frames have different colnames and rownames, so sometimes a NULL will pop out when I address a non-existent cell. Both data.frames have a list of 'lm' output in their cells.
But the problem is I keep getting this error:
Error in diff_models[i, j, "cont"] <- cont :
incorrect number of subscripts
I have also noticed that upon creation "diff_models" is a logical type (also strange, btw), but when the error pops out it becomes a list. So I guess the problem is about there being no [i,j,'cont'] in a list. But why does the loop change the type of "diff_models"?
cont_col <- colnames(temp1)
cont_row <- rownames(temp1)
dis_col <- colnames(temp2)
dis_row <- rownames(temp2)
cols <- unique(c(cont_col,dis_col))
rows <- unique(c(cont_row,dis_row))
diff_models <- array(NA, c(length(rows),length(cols),2), dimnames =
list('predictor'=rows,'response'=cols, 'condition'=c('dis','cont')))
for (j in cols) {
for (i in rows) {
cont <- cont_models[i,j]
dis <- dis_models[i,j]
diff_models[i,j,"dis"] <- ifelse(is.null(dis),NA,dis)
diff_models[i,j,"cont"] <- ifelse(is.null(cont),NA,cont)
}
}
Using
diff_models[i][j]["dis"] <- ifelse(is.null(dis),NA,dis)
diff_models[i][j]["cont"] <- ifelse(is.null(cont),NA,cont)
does not end up in an error but turns "diff_models" into an empty list.
Saving numerics into the array, however, work perfectly well
I am trying to apply a mathematical morphology operation on a binary image. The operation am trying to apply is dilation. I am posting the code below.
# Dilation of A with a square with size a. The reference is (1,1)
#
mm_dilationsqr <- function(A,a){
C <- A
if(a<=1) return(C)
for(i in 1:a)
for(j in 1:a)
{
B <- mm_translation(A,1-i,1-j)
C <- mm_union(C,B)
}
C <- mm_translation(C,a/2,a/2)
return(C)
}
The above is a dilation function which calls translation and union functions too which are posted below.
# Translation of set A by x,y.
# Warning: no periodicity, watch the borders!
#
mm_translation <- function(A,x,y){
C <- mm_zero()
if((x>=-M+1) & (x<=M) & (y>=-N+1) & (y<=N))
{
for(i in 1:M)
for(j in 1:N)
{
if((i+x>=0) & (i+x<=M) & (j+y>=0) & (j+y<=N))
C[i+x,j+y] <- A[i,j]
}
}
return(C)
}
Union function below:
# Union (OR) of sets A and B
#
mm_union <- function(A,B){
C<-as.integer(A|B)
dim(C) <- c(M,N)
return(C)
}
Now when am trying to process the image in array form using mm_dilation function, I am getting this error: Error in mm_union(C, B) : binary operation on non-conformable arrays.
My array dimensions are
dim(TA)
[1] 745 691
When am using a subset of the above given TA array of dimension given below, the code is working in that case.
dim(A)
[1] 21 21
So I want to know how I can improve this so that it can process image of TA dimensions.
numberofusers=75000
numberofitems=65000
number.of.factors=10
# N is a numberofusers*numberofitems sparse Matrix (loaded from a dataset).
#X,Y matrices are already available and have dimensions
# (numberofusers,number.of.factors) and
#(numberofitems,number.of.factors) respectively
ptempuser<-rep(0,numberofitems)
tempuser<-rep(0,numberofitems)
Y.big<-t(Y)%*%Y
for (i in 1:numberofusers) {
matrixproduct1 <- matrix(0,numberofitems,number.of.factors)
nonzerolistforthatuser <- which(N[i,]!=0)
tempuser[nonzerolistforthatuser] <- alpha*N[i,nonzerolistforthatuser]
ptempuser[nonzerolistforthatuser] <- 1
matrixproduct1[nonzerolistforthatuser,] <-tempuser[nonzerolistforthatuser]*Y[nonzerolistforthatuser,]
finalproductmatrix1 <- matrix(0,number.of.factors,number.of.factors)
finalproductmatrix1 <- t(Y)[,nonzerolistforthatuser] %*% matrixproduct1[nonzerolistforthatuser,]
tempuser <- 1+tempuser
matrixproduct2 <- t(Y)
matrixproduct2[,nonzerolistforthatuser] <- t(Y)[,nonzerolistforthatuser]*tempuser[nonzerolistforthatuser]
Agen<-Y.big + finalproductmatrix1
dim1<-dim(Y.big)
dim2<-dim(finalproductmatrix1)
if(dim1[1]!=dim2[1]){
print(i)
print(dim1[1])
print(dim2[1])
}
if(dim1[2]!=dim2[2]){
print(i)
print(dim1[2])
print(dim2[2])
}
finalproductmatrix2 <- matrixproduct2[,nonzerolistforthatuser] %*% cbind(ptempuser[nonzerolistforthatuser])
X[i,] <- (ginv(Y.big+finalproductmatrix1+diag(rep(lambda,number.of.factors))))%*%(finalproductmatrix2)
}
I get the error as 'Error in Y.big + finalproductmatrix1 : non-conformable arrays' . But I even tried doing Agen<-Y.big+ final productmatrix1 inside the function and that has no problem. So surely the dimensions are not causing a problem. Still I get non conformable.
Please tell me what to do. I am stuck on this for hours. I have also checked for the dimension condition and that shows no print results. So I am confused.
I have an array that can have one or more pages or sheets (my names for the third dimension). I am attempting to perform operations on the array. When there is only one sheet or page the result of the operation is a matrix. I would like the result to be an array. Is there a way to retain the class array even when the result of the operation has only 1 sheet or page?
Here is an example. I would like my.var.2 and my.var.3 to be arrays. The variable my.pages is set to 1 here, which seems to be causing the problem. However, my.pages can be >1. If my.pages <- 2 then my.var.2 and my.var.3 are arrays.
set.seed(1234)
my.rows <- 10
my.columns <- 4
my.pages <- 1
my.var.1 <- array( rnorm((my.rows*my.columns*my.pages), 10, 2),
c(my.rows,my.columns,my.pages))
my.var.1
my.var.2 <- 2 * my.var.1[,-my.columns,]
my.var.3 <- 10 * my.var.1[,-1,]
class(my.var.2)
class(my.var.3)
my.var.2 <- as.array(my.var.2)
my.var.3 <- as.array(my.var.3)
class(my.var.2)
class(my.var.3)
my.var.2 <- as.array( 2 * my.var.1[,-my.columns,])
my.var.3 <- as.array(10 * my.var.1[,-1,] )
class(my.var.2)
class(my.var.3)
The switch to matrix causes problems when I try to use my.var.1 and my.var.2 in nested for-loops.
The following if statement seems to solve the problem, but also seems a little clunky. Is there a more elegant solution?
if(my.pages == 1) {my.var.2 <- array(my.var.2, c(my.rows,(my.columns-1),my.pages))}
From help([):
Usage:
x[i, j, ... , drop = TRUE]
...
drop: For matrices and arrays. If 'TRUE' the result is coerced to
the lowest possible dimension (see the examples). This only
works for extracting elements, not for the replacement. See
'drop' for further details.
Your code, revisited:
set.seed(1234)
my.rows <- 10
my.columns <- 4
my.pages <- 1
my.var.1 <- array( rnorm((my.rows*my.columns*my.pages), 10, 2),
c(my.rows,my.columns,my.pages))
my.var.2 <- 2 * my.var.1[,-my.columns,,drop=FALSE]
my.var.3 <- 10 * my.var.1[,-1,,drop=FALSE]
class(my.var.2)
## [1] "array"
class(my.var.3)
## [1] "array"