使用索引来引用 dplyr 中的 summarise() 中的列 - R

Posted

技术标签:

【中文标题】使用索引来引用 dplyr 中的 summarise() 中的列 - R【英文标题】:Using index to reference column in summarise() in dplyr - R 【发布时间】:2017-03-21 11:01:39 【问题描述】:

我想用它的索引而不是它的名称来引用 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

如何在汇总子句中使用“卧室”列的索引而不是其名称?我试过了:

     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

我的目标可以实现吗?如果可以,如何实现?谢谢。

【问题讨论】:

你可能会发现这个相关的***.com/questions/32618744/… 在@MFR 链接的答案中,一位评论者指出.[[4]] 语法不适用于group_by。可悲的是,这只能解释为什么它不起作用:)。 【参考方案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 

或者,有基础

aggregate(d[ ,5] ~ timepoint, data = d, mean)

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

【讨论】:

您的代码有效,但给出了汇总结果。我想按“访问”对结果进行分组,并在左侧显示“访问”列。 那么,考虑到所需的输出,聚合工作不完美吗?即aggregate(hp ~ cyl, mtcars, mean)。另一种选择是将%&gt;% as.data.frame() 添加到上面的代码中,这会将分组变量列为行名称。 我明白你的意思,它是有效的。但是,我认为我的情况比您使用的示例要复杂一些。就我而言,有两个分类变量。首先,一个分类变量中的值必须水平分布,其次,这些值应该按第二个分类变量分组。虽然在您的示例中只有一个分类变量在起作用,即 cyl。 查看编辑。我读了你的数据并做了同样的事情。这行得通吗?【参考方案2】:

我找到的答案是dplyr的summarize_at()函数。以下是我如何使用 summarise_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

【讨论】:

以上是关于使用索引来引用 dplyr 中的 summarise() 中的列 - R的主要内容,如果未能解决你的问题,请参考以下文章

使用 SQL Server 索引来提高性能

我如何使用视图和索引来提高性能

MySQL 是不是使用现有索引来创建新索引?

如何改善数据库的结构,以及如何使用索引来缩短搜索时间

高效的 SQL 查询或索引来查找所有列是不是只有 1 个值

SAS:如何使用索引来挑选宏数组变量