数据操作使 lapply 不起作用

Data manipulation makes lapply not work

编辑: 好的,它与 data.all.filtered 数据类型有关。

筛选的数据类型是从 data.all.raw 创建的,它适用于下面的任何 lapply。奇怪的是我不知道这两者有什么不同...

data.selectedFeatures <- sapply(data.train.raw, FUN = sf.getGoodFeaturesVector, treshold = 5)

data.train.filtered <- lapply(seq(1, 8), FUN = function(i) sf.filterFeatures(data.train.raw[[i]], data.selectedFeatures[[i]]))

st.testFeature <- function(featureVector, treshold) {
  if(!is.numeric(featureVector)) {return(T)}

  numberOfNonZero <- sum(featureVector > 0)
  numberOfZero <- length(featureVector) - numberOfNonZero

  return(min(numberOfNonZero, numberOfZero) >= treshold)
}

sf.getGoodFeaturesVector <- function(data, treshold) {

  selectedFeatures <- sapply(data, FUN = st.testFeature, treshold <- treshold)
  whitelistedFeatures <- names(data) %in% c("id", "tp")

  return(selectedFeatures | whitelistedFeatures)

}

sf.filterFeatures <- function(data, selectedFeatures) {
  return(data[, selectedFeatures])
}

知道我在操作导致后续 lapply 无法工作的数据时做错了什么吗?

原文post:

我有一个名为 data.train.filtered 的数据集列表,我想获得一个模型列表(用于预测一个名为 tp 的特征),这些模型由 rplot 训练。我能想到的最简单的解决方案是使用 lapply 但由于某些原因它不起作用。

lapply(data.train.filtered, function(dta) rpart(tp ~ ., data = dta))

Error in terms.formula(formula, data = data) : 
  '.' in formula and no 'data' argument 

问题可能不在数据中,因为仅对一个(任何)数据集使用它就可以正常工作:

rpart(tp ~ ., data = data.train.filtered[[1]])

即使使用 lapply 通过索引仅访问一个数据集工作正常(如上所示),但槽索引失败的方式与第一个示例相同。

lapply(1:8, function(i) rpart(tp ~ ., data = data.train.filtered[[i]])) 

Error in terms.formula(formula, data = data) : 
  '.' in formula and no 'data' argument 

索引版本的回溯如下:

10 terms.formula(formula, data = data) 
9 terms(formula, data = data) 
8 model.frame.default(formula = tp ~ ., data = data.train.filtered[[i]], 
    na.action = function (x) 
    {
        Terms <- attr(x, "terms") ... 
7 stats::model.frame(formula = tp ~ ., data = data.train.filtered[[i]], 
    na.action = function (x) 
    {
        Terms <- attr(x, "terms") ... 
6 eval(expr, envir, enclos) 
5 eval(expr, p) 
4 eval.parent(temp) 
3 rpart(tp ~ ., data = data.train.filtered[[i]]) 
2 FUN(X[[i]], ...) 
1 lapply(1:8, function(i) rpart(tp ~ ., data = data.train.filtered[[i]])) 

我很确定我在这里遗漏了一些非常微不足道的东西,但是我对 RI 还很陌生,我就是找不到问题所在。

PS:我知道我可以通过 for 循环遍历所有数据集,但这感觉真的很脏,我更喜欢 R 惯用的解决方案。

使用 data(iris)purrr::map:

datas <- split(iris, rep(sample(c(1,2,3)), length.out = nrow(iris))
models <- purrr::map(datas, ~ rpart(Species ~ ., data = .x)) # a better syntax

诀窍是在原始列表上使用 lapply(),而不是在索引向量上。例如:

# toy data:
data.train.filtered <- list()
# create 10 different length data frames:
for(i in 1:10){
  n <- rpois(1, 15)
  x = rnorm(n)
  data.train.filtered[[i]] <- data.frame(x =x,
                                         tp = 3 + 2 * x + rnorm(n)
  )
}

library(rpart)
lapply(data.train.filtered, function(dta){rpart(tp ~ ., data = dta)})

好的,我终于找到了答案。问题是 data.train.all 实际上不是我想的那样。我在过滤过程中出错,它破坏了(悄悄地,感谢 R)一切。

解决方法是使用:

data.selectedFeatures <- lapply(data.train.raw, FUN = sf.getGoodFeaturesVector, treshold = 5)

而不是

data.selectedFeatures <- sapply(data.train.raw, FUN = sf.getGoodFeaturesVector, treshold = 5)

不过,感谢所有其他答案。