我有一个矩阵列表,我正在尝试将函数应用于每个矩阵的每一列。我认为,这样做的自然方法是将apply
嵌套在lapply
中,但是当我这样做时,它会给我一个错误:
library(hydroGOF) # for the mse function
# Create a vector for comparison
A <- rnorm(10)
# Create a list of matrices to be looped over
B <- rnorm(10 * 5 * 3)
list.element.number <- rep(1:3, 50)
B.list <- split(B, list.element.number)
B.list <- lapply(B.list, matrix, ncol = 5, nrow = 10) # A 3 element list of 10 x 5 matrices
# Wrapper function for mse
my.mse <- function(sim) {
mse(sim, A)
}
# I'm trying to loop through each column of B.list and compare it to A
lapply(B.list, apply, MARGIN = 2, FUN = my.mse)
# Error in FUN(X[[1L]], ...) :
# unused arguments (function (X, MARGIN, FUN, ...)
# {
# FUN <- match.fun(FUN)
# dl <- length(dim(X))
# if (!dl) stop("dim(X) must have a positive length")
# if (is.object(X)) X <- if (dl == 2) as.matrix(X) else as.array(X)
# d <- dim(X)
# dn <- dimnames(X)
# ds <- seq_len(dl)
# if (is.character(MARGIN)) {
# if (is.null(dnn <- names(dn))) stop("'X' must have named dimnames")
# MARGIN <- match(MARGIN, dnn)
# if (anyNA(MARGIN)) stop("not all elements of 'MARGIN' are names of dimensions")
# }
# s.call <- ds[-MARGIN]
# s.ans <- ds[MARGIN]
# d.call <- d[-MARGIN]
# d.ans <- d[MARGIN]
# dn.call <- dn[-MARGIN]
# dn.ans <- dn[MARGIN]
# d2 <- prod(d.ans)
# if (d2 == 0) {
# newX <- array(vector(typeof(X), 1), dim = c(prod(d.call), 1))
# ans <- FUN(if (length(d.call) < 2) newX[, 1] else array(newX[, 1], d.call, dn.call), ...)
# return(if (is.null(ans)) ans else if (length(d.ans) < 2) ans[1][-1] else array(ans, d.ans, dn.a
理想情况下,这会给我一个3元素列表,其中每个元素是一个5元素向量,但我得到一个错误。有没有人知道如何解决这个问题(除了for
循环,感觉不优雅),或者出了什么问题?
答案 0 :(得分:4)
FUN=my.mse
正在劫持您对lapply
apply
的尝试。我想你想要:
lapply(B.list, function(x) apply(x, 2, my.mse))
您不能在同一个调用中为FUN
和lapply
指定apply
(除非您使用Konrad建议的位置匹配)。发生的事情是你的电话匹配如下:
lapply(B.list, FUN=my.mse, ...=list(apply, MARGIN=2))
然后在第一次迭代中导致尝试评估:
my.mse(B.list[[1]], apply, MARGIN=2)
而不是您预期的apply(B.list[[1]], 2, my.mse)
。由于my.mse
只接受一个参数,因此您会收到有关“未使用的参数”的错误。仔细观察,“未使用的参数”是apply
函数的主体。