Apply function or Loop in R: Not numerical, returning NA

598 views Asked by At

I am working with a resampling procedure in R (just like a bootstrap). I have a matrix of response/explanatory variables and would like to make 999 samples of this matrix to calculate for each statistic I am working their mean, sd and confidence interval. So, I wrote a function to calculate and to return a list:

mydata <- data.frame(a=rnorm(20, 1, 1), b = rnorm(20,1,1))

myfun <- function(data, n){
  sample <- data[sample(n, replace = T),]
  model1 <- lm(sample[,1]~sample[,2])
  return(list(model1[[1]][[1]], model1[[1]][[2]]))
}

result <- as.numeric()
result <- replicate(99, myfun(mydata, 10))

Then, I have a matrix as my output in which the rows are the statistics and the columns are the samplings (nrow = 2 and ncol = 99). I need the mean and sd for each row, but when I try to use the apply function or even a loop the following message shows up:

In mean.default(newX[, i], ...) :
argument is not numeric or logical: returning NA

Moreover:

is.numeric(result)
[1] FALSE

I found it strange, because I never had such problem with similar procedures.

Any thoughts?

4

There are 4 answers

0
Zheyuan Li On BEST ANSWER

Use the following:

myfun <- function(dat, n){
  dat1 <- dat[sample(n, replace = T),]
  model1 <- lm(dat1[,1] ~ dat1[,2])
  return(coef(model1))
  }

replicate(99, myfun(mydata, 10))
0
akrun On

The reason is the 'result' is a list of 198 elements with dimension attributes. We need to unlist the 'result' and provide the dimension attributes

result1 <- `dim<-`(unlist(result), dim(result))

and then use the apply

2
Yollanda Beetroot On

Just replace list() by c() in your myfun() function

mydata <- data.frame(a=rnorm(20, 1, 1), b = rnorm(20,1,1))

myfun <- function(data, n){
  sample <- data[sample(n, replace = T),]
  model1 <- lm(sample[,1]~sample[,2])
  return(c(model1[[1]][[1]], model1[[1]][[2]]))
}

result <- as.numeric()
result <- replicate(99, myfun(mydata, 10))

apply(result, FUN=mean, 1)
apply(result, FUN=sd, 1)
0
Derek Corcoran On

This worked for me:

mydata <- data.frame(a=rnorm(20, 1, 1), b = rnorm(20,1,1))

myfun <- function(data, n){
  sample <- data[sample(n, replace = T),]
  model1 <- lm(sample[,1]~sample[,2])
  return(data.frame(v1 = model1[[1]][[1]], v2 = model1[[1]][[2]]))
}

result <- do.call("rbind",(replicate(99, myfun(mydata, 10), simplify = FALSE)))