【问题标题】:Looping through list of columns循环遍历列列表
【发布时间】:2020-05-31 09:15:39
【问题描述】:

我有一个大数据框,一列显示受访者来自的省份。我希望根据列名(例如,对于希望、责任、功效等列),在某些列中查看各省受访者之间的值差异。

Province  Hope  Responsibility  Efficacy Age
   A       4         3            2      24
   A       2         1            4      23
   C       5         3            5      20
   B       3         2            3      29
   A       1         1            4      23
   B       3         3            2      25

到目前为止,我遍历了每列的所有省份组合之间的差异:

list1 = list('A', 'B', 'C', 'D' 'E', 'F')
list2 = list('B', 'C', 'D' 'E', 'F')

for (i in list1){
  for (j in list2){
    t <- t.test(dt[Province == i, Hope], dt[Province == j, Hope])
    if (t$p.value <= 0.05){
      print(paste("Results:",i,"and",j))
      print(t)
    }}}

如何创建一个循环,根据列名循环遍历列列表,例如像这样的东西(不起作用)。

此部分已编辑

list1 = list('A', 'B', 'C', 'D' 'E', 'F')
list2 = list('B', 'C', 'D' 'E', 'F')
list3 = list('Hope', 'Responsibility', 'Efficacy')

for (c in list3){
  for (i in list1){
    for (j in list2){
      t <- t.test(dt[Province == i, c], dt[Province == j, c])
      if (t$p.value <= 0.05){
        print(paste("Results:",i,"and",j))
        print(t)
      }}}}

【问题讨论】:

    标签: r loops for-loop


    【解决方案1】:

    您可以先获取Provinceunique 值,然后使用lapply 迭代dt 的列名,然后使用outer 获取每个组合的p 值t.test

    list1 <- unique(dt$Province)
    
    apply_t_test <- function(x, y, col) {
            t.test(dt[dt$Province == x, col], dt[dt$Province == y, col])$p.value
    }
    apply_t_test <- Vectorize(apply_t_test)
    cols <- c('Hope', 'Responsibility', 'Efficacy')
    
    result <- sapply(cols, function(column) outer(list1, list1, function(x, y) 
                   apply_t_test(x, y, column)), simplify = FALSE)
    

    result 看起来像这样:

    #$Hope
    #           [,1]       [,2]       [,3]
    #[1,] 1.00000000 0.01146182 0.77720749
    #[2,] 0.01146182 1.00000000 0.02880269
    #[3,] 0.77720749 0.02880269 1.00000000
    
    #$Responsibility
    #          [,1]      [,2]      [,3]
    #[1,] 1.0000000 0.8624039 0.5206825
    #[2,] 0.8624039 1.0000000 0.3795635
    #[3,] 0.5206825 0.3795635 1.0000000
    
    #$Efficacy
    #          [,1]      [,2]      [,3]
    #[1,] 1.0000000 0.6411564 0.5822007
    #[2,] 0.6411564 1.0000000 0.9467599
    #[3,] 0.5822007 0.9467599 1.0000000
    

    【讨论】:

    • 谢谢!但是,数据表包含更多列,我只想根据列名对特定列运行 t 检验。
    • @MacOS OP 的数据不足以获得有意义的结果。你需要生成一些假数据来获取result
    • @Schoguan 您也可以对特定列运行此操作。您可以按名称选择列,也可以按名称或列号等模式选择列。您要在哪些列上运行 t.test?
    • @RonakShah 感谢您指出这一点!我错过了。然而,这不是一个最小可行的例子。
    • 好像你有data.table,你能先运行这个setDF(dt)把它改成dataframe再试试上面的吗?
    【解决方案2】:

    我不知道你想要达到什么,对不起。但是,据我所知,您的代码和逻辑中有两个错误。

    首先,如何选择行和列

    dt[Province == i, Hope]
    

    这只有在您在某处定义了Province 时才有效。但是,根据您的逻辑,这似乎没有意义,因为您要选择 dt 的行。 Hope 也是如此。如果要选择列Hope,则需要传入一个字符。这导致以下代码。

    dt[dt$Province == i, "Hope"]
    

    也就是说,我认为你真正想要的是

    dt[dt$Province == i, c]
    

    因为您已经定义了 list list3 并对其进行循环,但您没有使用它。

    其次,您致电t.test。根据以上观察,我们有

    t.test(dt[dt$Province == i, c], dt[dt$Province == j, c])
    

    这是行不通的,因为这会产生不同长度的向量。例如,在循环的第一个循环中,您将拥有

    dt[dt$Province == "A", "Hope"] = (4, 2, 1)
    dt[dt$Province == "B", "Hope"] = (3, 3)
    

    这是行不通的,因为t.test 假定两个向量长度相等。

    我希望这会有所帮助。另外,请查看@Ronak Shah 的答案。

    【讨论】:

    • 谢谢!我在示例中确实有一个错误,并在上面的原始帖子中进行了编辑(关于不循环列表 3)。关于“省”-> 这是列的名称,适用于我发布的第一段代码。
    猜你喜欢
    • 2013-06-22
    • 2017-03-02
    • 1970-01-01
    • 2018-10-26
    • 2013-09-04
    • 2019-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多