使用dplyr中的summarise()函数时如何通过索引引用列? - R

4

我希望在dplyr的summarise()函数中,使用列的索引而不是列名进行引用。例如:

        > a

           id visit timepoint bedroom  den
            1   0     0        62      NA 
            2   1     0        53    6.00  
            3   2     0        56    2.75   
            4   0     1        55      NA 
            5   1     2        61      NA 
            6   2     0        54      NA 
            7   0     1        58    2.75   
            8   1     2        59      NA 
            9   2     2        60      NA 
            10  0     1        57      NA 

           # E.g. 
           a %>% group_by(visit) %>% summarise(avg.bedroom = mean(bedroom, na.rm   =T)
           # Returns
        visit avg.dedroom
        <dbl>       <dbl>
     1     0       4.375
     2     1       2.750
     3     2         NaN

我该如何在summarise语句中使用“bedroom”列的索引而不是它的名称?我尝试过:

     a %>% group_by(visit) %>% summarise("4" = mean(.[[4]], na.rm = T))

但是这返回了错误的结果:

       visit      `4`
        <dbl>    <dbl>
      1     0 3.833333
      2     1 3.833333
      3     2 3.833333

我的目标能实现吗?如果可以,怎么做?谢谢。

1
你可能会发现这个相关的 https://dev59.com/zFwY5IYBdhLWcg3wcXaE - MFR
1
在答案@MFR中,一位评论者指出.[[4]]语法与group_by不兼容。遗憾的是,这只是解释了为什么它不起作用 :)。 - Paul Hiemstra
2个回答

1
也许不完全符合您的要求,但一个选择是使用purrr而不是dplyr。类似这样的东西。
# Read in data
d <- read.table(textConnection(" id visit timepoint bedroom  den
        1  12     0        62      NA 
        2  14     0        53    6.00  
        3  14     0        56    2.75   
        4  14     1        55      NA 
        5  14     2        61      NA 
        6  15     0        54      NA 
        7  15     1        58    2.75   
        8  16     2        59      NA 
        9  16     2        60      NA 
        10 17     1        57      NA "), 
    header = TRUE)


library(purrr)

d %>% 
    split(.$timepoint) %>% 
    map_dbl(function(x) mean(x[ ,5], na.rm = TRUE))

#     0     1     2 
# 4.375 2.750   NaN 

或者,使用基础(base)
aggregate(d[ ,5] ~ timepoint, data = d, mean)

#   timepoint d[, 5]
# 1         0  4.375
# 2         1  2.750

你的代码可以运行,但是给出了聚合结果。我想按照“访问”分组结果,并在左侧显示“访问”列。 - pv7
那么,考虑到期望的输出,aggregate(hp ~ cyl, mtcars, mean) 不是完美地工作吗?另一个选项是在上面的代码中添加 %>% as.data.frame(),这将把分组变量列出为行名。 - Daniel Anderson
我理解你的观点,它是有道理的。然而,我认为我的情况比你所使用的例子要复杂一些。在我的情况下,有两个分类变量。首先,一个分类变量中的值必须水平分布,其次这些值应该按照第二个分类变量进行分组。而在你的例子中,只有一个分类变量 cyl 参与其中。 - pv7
看一下修改后的内容。我读取了你的数据并做了相同的事情。这样可以吗? - Daniel Anderson

0
我找到的答案是 dplyr 的 summarize_at() 函数。这是我如何使用 summarize_at() 在数据框的子集上创建摘要统计信息的方式,其中列事先未知(对象是我的原始数据框,它以长格式存在,并具有一个列--房间--包含房间名称,以及两个其他列“访问”和“值”)。
          # Convert object to a wide form

          object$row <- 1 : nrow(object)

          y <- spread(object, room, value)


          # Remove the row column from y

          y <- y %>% select(-row)

          # Initialize stat1, the dataframe with the summary
          # statistics

          stat1 <- data.frame(visit = c(0, 1, 2))

          # Find the number of columns that stat1 will eventually
          # have

          y <- y %>% filter(id == id) %>% 
              select_if(function(col) mean(is.na(col)) != 1) 

          n <- ncol(y)

          # Append columns with summary statistics to stat1

          for (i in 3 : n) {
              t <- y %>% group_by(visit) %>% 
                  summarise_at(c(i), mean, na.rm = T)

              t[, 2] <- round(t[, 2], 2)

              stat1 <- cbind(stat1, t[, 2])
          }

          # Pass the dataframe stat1 to the list "results"

          results$stat1 <- stat1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接