【问题标题】:Using lapply on a diverse list in R在 R 中的不同列表上使用 lapply
【发布时间】:2020-06-22 10:09:30
【问题描述】:

我创建了一个包含子列表的列表,每个子列表都包含我希望 R 执行的一项任务的信息。

df <- as.data.frame(matrix(1:6 , ncol =2 , nrow = 3))
colnames(df) <- c("Col1", "Col2")
myList <- list()
myList[["Dataset1"]] <- list()
myList[["Dataset1"]]["Function"] <- "mean" 
myList[["Dataset1"]][["DataFrame"]] <- df
myList[["Dataset2"]] <- list()
myList[["Dataset2"]]["Function"] <- "lm" 
myList[["Dataset2"]][["DataFrame"]] <- df*2

现在我希望 R 将函数应用于数据框并将结果存储在新列表中。我怎样才能做到最好?

到目前为止,我有两个想法:我要么使用 lapply 遍历列表,每次访问子列表中的几个项目,将其提供给新函数

myResult <- lapply(myList, FUN = myList[["Dataset1"]]["Function"](x) , x = as.matrix(myList[["Dataset1"]][["DataFrame"]]))

但我不知道如何告诉 R 如何正确循环遍历子列表。

其次,我希望能够将整个子列表发送到一个函数,但我也无法让它运行。

myFunction <- function(x){
  TempData <- x[["DataFrame"]]
  TempFunction <- x["Function"]
  
  TempResult <- get(TempFunction)(TempData)
  
  return(TempResult)
}

myResult <- lapply(myList, myFunction(x))

如果有人能告诉我如何解决这个 id,我会非常高兴。

提前非常感谢!

【问题讨论】:

  • 如何将mean 函数应用于数据框?

标签: r list function lapply


【解决方案1】:

听起来比它应该的要复杂.. 并且不清楚您将如何应用 mean() 或 lm()。下面是一个将函数作为对象存储在列表中的示例:

myList[["Dataset1"]] <- list()
myList[["Dataset1"]][["Function"]] <- function(x)mean(as.matrix(x))
myList[["Dataset1"]][["DataFrame"]] <- df
myList[["Dataset2"]] <- list()
myList[["Dataset2"]][["Function"]] <- function(x){lm(Col2~Col1,data=x)}
myList[["Dataset2"]][["DataFrame"]] <- df*2

所以你遍历列表中的元素,你会得到每个元素的 function(dataframe) 的结果:

lapply(myList,function(i)i$Function(i$DataFrame))
$Dataset1
[1] 3.5

$Dataset2

Call:
lm(formula = Col2 ~ Col1, data = x)

Coefficients:
(Intercept)         Col1  
          6            1  

【讨论】:

  • 谢谢,我认为将函数存储在列表中会有很大帮助。
【解决方案2】:

您可以做的第一件事是使用match.fun 函数,该函数允许您从字符串中恢复函数。应用于循环,它返回以下解决方案:

list<-list()
for (i in 1:length(myList)){
 TempFunc <- match.fun(myList[[i]][["Function"]])
 Results <- TempFunc(myList[[i]][["DataFrame"]])
 list[i]<-Results
}

> list
[[1]]
[1] NA

[[2]]
(Intercept)        Col2 
         -6           1 

其实函数没有意义,因为函数不合适。

【讨论】:

  • 谢谢,我也想过一个循环,但我曾经读到 apply 更快,更容易并行化(用于多核使用)。函数没有意义,真实数据稍微复杂一些,但为了简单起见,我只是使用了一些微不足道的东西。 Sum 可以在矩阵上工作,但我猜不是数据框。我会尝试匹配功能!
【解决方案3】:

函数call 允许您通过以字符串形式给出的名称调用函数,并且您可以使用eval 评估此调用。但请注意,您的函数调用都不适用于数据框:

lapply(myList, function(sublist) call(sublist$Function, sublist[["DataFrame"]]))
#> $Dataset1
#> mean(list(Col1 = 1:3, Col2 = 4:6))

#> $Dataset2
#> lm(list(Col1 = c(2, 4, 6), Col2 = c(8, 10, 12)))

所以结果对于所使用的示例来说是无用的:

lapply(myList, function(sublist) eval(call(sublist$Function, sublist[["DataFrame"]])))
#> $Dataset1
#> [1] NA
#> 
#> $Dataset2
#> 
#> Call:
#> lm(formula = structure(list(Col1 = c(2, 4, 6), Col2 = c(8, 10, 
#> 12)), class = "data.frame", row.names = c(NA, -3L)))
#> 
#> Coefficients:
#> (Intercept)         Col2  
#>          -6            1  
#> 
#> 
#> Warning message:
#> In mean.default(list(Col1 = 1:3, Col2 = 4:6)) :
#>   argument is not numeric or logical: returning NA

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 2015-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-16
    • 2012-10-16
    相关资源
    最近更新 更多