Reputation: 455
I have seen a couple related questions on this topic, for instance here and here but the solutions don't seem to work for me as far as I can tell.
I have a function that returns a 5x3 matrix. I use mapply to iterate the function 4 times. My goal is to have the mapply call return a 20x3 matrix, but instead it returns a 15x4 matrix.
population <- runif(100, 0, 1)
iterations <- seq(1:4)
test.func <- function(k){
samp1 <- sample(population, 20, replace = FALSE)
samp2 <- sample(population, 20, replace = FALSE)
samp3 <- sample(population, 20, replace = FALSE)
## Pre-allocate
c1 <- NULL
c2 <- NULL
c3 <- NULL
for (i in 1:5){
c1[i] <- samp1[i]
c2[i] <- samp2[i]
c3[i] <- samp3[i]
}
combined <- cbind(c1, c2, c3)
print(combined)
}
results <- mapply(FUN = test.func, k = iterations)
I tried a transpose within the function, but that didn't help. I'd be open to options that fix the problem after calling mapply too.
One alternative would be to convert the 5x3 matrices to data frames and then separate them into a 3x20 matrix and transpose it. But I am hoping there is a more sensible way.
Upvotes: 0
Views: 247
Reputation: 99351
mapply
is a multivariate version of sapply
, which simplifies its result using simplify2array
(unless you tell it otherwise). You don't need to use mapply
since you only have one variable being passed to your function (actually, you have no variables being passed - see below). In base R, you can use
do.call(rbind, lapply(iterations, test.func))
Other options that can replace do.call(rbind, ...)
are data.table::rbindlist
and plyr::rbind.fill
Also, you're never passing k
into the function, so you could even use replicate
. But again, since replicate
is essentially sapply
you'd need simplify = FALSE
test.func() ## notice that k is not used at all
# c1 c2 c3
# [1,] 0.6087179 0.04439165 0.11227567
# [2,] 0.8915234 0.79688365 0.02446302
# [3,] 0.5635389 0.17794940 0.16731767
# [4,] 0.7040224 0.17201792 0.28175588
# [5,] 0.8999534 0.28175588 0.58302149
PS - I also condensed your last two lines in to one
combined <- cbind(c1, c2, c3)
print(combined)
can just be
cbind(c1, c2, c3)
That print
call can make things frustrating when you assign x <- test.func()
Upvotes: 2