【问题标题】:how to assign each element of a list as arguments to a function in a loop in R?如何将列表的每个元素作为参数分配给R循环中的函数?
【发布时间】:2018-10-07 19:26:45
【问题描述】:

我是 R 新手。我想根据因子列(例如 A 列和乙)。首先,我希望通过将 A 列和 B 列分组,然后单独由 A 和 B 单独进行相同的操作来获得结果。我编写了一个类似于下面的代码。我有一个要测试的因子组合列表(groupList),然后对于循环的每次迭代,我将该列表的一个元素作为“by”的参数提供。但是,您肯定可以看到,它不起作用。 R 不将列表的元素识别为函数“by”的参数。关于如何使这项工作的任何想法?欢迎和赞赏任何指针或建议。

groupList <- list(".(A, B)", "A", "B")

for(i in 1:length(groupList)){
  output <- dt[,list(mean=mean(C),
                     sd=sd(C),
                     min=min(C),
                     median=median(C),
                     max=max(C)),
               by = groupList[i]]

  Here insert code to save each output
}

【问题讨论】:

  • 您能否制作数据框的最小子集,例如df,然后将dput(df) 的输出粘贴到您的问题中?
  • 但是,如果我是你,我会做三个单独的拆分-应用-组合,而不是在按两个变量分组后创建一个列表。这很容易完成,例如dplyr::summarise 函数族。

标签: r arguments


【解决方案1】:

我猜aggregate 函数可以解决你的问题。假设您有一个数据框 df 包含三列 A,B,C,如下所示:

df<-data.frame(A=rep(letters[1:3],3),B=rep(letters[4:6],each=3),C=1:9)

如果您想通过因子 A 计算 C 的平均值,请尝试:

aggregate(formula=C~A,data=df,FUN=mean)

通过因子B,尝试:

aggregate(formula=C~B,data=df,FUN=mean)

通过因子AB,尝试:

aggregate(formula=C~A+B,data=df,FUN=mean)

【讨论】:

    【解决方案2】:

    您的groupList 可以重组为字符向量列表。然后您可以使用lapply 或现有的for 循环并添加eval() 来正确解释by= 输入:

    set.seed(1)
    dt <- data.table(A=rep(1:2,each=5), B=rep(1:5,each=2), C=1:10)
    
    groupList <- list(c("A", "B"), c("A"), c("B"))
    
    lapply(
      groupList,
      function(x) {
        dt[, .(mean=mean(C), sd=sd(C)), by=x]
      }
    )
    
    out <- vector("list", 3)
    for(i in 1:length(groupList)){
      out[[i]] <- dt[, .(mean=mean(C), sd=sd(C)), by=eval(groupList[[i]]) ]
    }
    
    str(out)
    #List of 3
    # $ :Classes ‘data.table’ and 'data.frame':      6 obs. of  4 variables:
    #  ..$ A   : int [1:6] 1 1 1 2 2 2
    #  ..$ B   : int [1:6] 1 2 3 3 4 5
    #  ..$ mean: num [1:6] 1.5 3.5 5 6 7.5 9.5
    #  ..$ sd  : num [1:6] 0.707 0.707 NA NA 0.707 ...
    #  ..- attr(*, ".internal.selfref")=<externalptr> 
    # $ :Classes ‘data.table’ and 'data.frame':      2 obs. of  3 variables:
    #  ..$ A   : int [1:2] 1 2
    #  ..$ mean: num [1:2] 3 8
    #  ..$ sd  : num [1:2] 1.58 1.58
    #  ..- attr(*, ".internal.selfref")=<externalptr> 
    # $ :Classes ‘data.table’ and 'data.frame':      5 obs. of  3 variables:
    #  ..$ B   : int [1:5] 1 2 3 4 5
    #  ..$ mean: num [1:5] 1.5 3.5 5.5 7.5 9.5
    #  ..$ sd  : num [1:5] 0.707 0.707 0.707 0.707 0.707
    

    【讨论】:

    • 谢谢。两个非常优雅的解决方案。我会选择使用 lapply 的那个,我会记住另一个使用 for 循环的。
    【解决方案3】:

    为了演示,我使用了mtcars 数据集。这是dplyr 包的一种方法。

    library(dplyr)
    
    # create a vector of functions that you need
    describe <- c("mean", "sd", "min", "median", "max")
    
    # group by the variable gear
    mtcars %>%
      group_by(gear) %>%
      summarise_at(vars(mpg), describe) 
    
    # group by the variable carb
    mtcars %>%
      group_by(carb) %>%
      summarise_at(vars(mpg), describe) 
    
    # group by both gear and carb
    mtcars %>%
      group_by(gear, carb) %>%
      summarise_at(vars(mpg), describe) 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-02
      • 2021-07-02
      • 2020-09-27
      • 2017-04-09
      • 1970-01-01
      • 2016-06-11
      • 1970-01-01
      相关资源
      最近更新 更多