【问题标题】:Use pipe operator %>% with replacement functions like colnames()<-将 %>% 与 colnames()<- 等替换函数一起使用
【发布时间】:2015-03-21 22:53:06
【问题描述】:

我如何使用管道运算符来管道到 colnames()&lt;- 之类的替换函数?

这是我想要做的:

library(dplyr)
averages_df <- 
   group_by(mtcars, cyl) %>%
   summarise(mean(disp), mean(hp))
colnames(averages_df) <- c("cyl", "disp_mean", "hp_mean")
averages_df

# Source: local data frame [3 x 3]
# 
#   cyl disp_mean   hp_mean
# 1   4  105.1364  82.63636
# 2   6  183.3143 122.28571
# 3   8  353.1000 209.21429

但理想情况下应该是这样的:

averages_df <- 
  group_by(mtcars, cyl) %>%
  summarise(mean(disp), mean(hp)) %>%
  add_colnames(c("cyl", "disp_mean", "hp_mean"))

有没有办法不用每次都写一个专门的函数来做到这一点?

这里的答案是一个开始,但不完全是我的问题:Chaining arithmetic operators in dplyr

【问题讨论】:

  • 你可以将你的输入命名为summarise - group_by(mtcars, cyl) %&gt;% summarise(disp_mean=mean(disp), hp_mean=mean(hp)) 虽然我不知道使用colnames 有多大的拖累。每件小事都必须在 dplyr 中完成吗?
  • 我相信dplyr 中有一个rename() 函数。或者,是的,按照@thelatemail 所说的去做。
  • 或者只使用setNames,如group_by(mtcars, cyl) %&gt;% summarise(mean(disp), mean(hp)) %&gt;% setNames(., c("cyl", "disp_mean", "hp_mean"))
  • @DavidArenburg - 现在我为什么没有想到这一点,因为我刚刚在 2 分钟前指出了这一点?
  • @thelatemail 我正在写"names&lt;-"(., ... 然后我告诉自己“等一下”...

标签: r dplyr magrittr


【解决方案1】:

我们可以通过使用summarise_at.funs 参数和dplyr 为汇总变量添加后缀,如下代码。

library(dplyr)

# summarise_at with dplyr
mtcars %>% 
  group_by(cyl) %>%
  summarise_at(
    .cols = c("disp", "hp"),
    .funs = c(mean="mean")
  )
# A tibble: 3 × 3
# cyl disp_mean   hp_mean
# <dbl>     <dbl>     <dbl>
# 1     4  105.1364  82.63636
# 2     6  183.3143 122.28571
# 3     8  353.1000 209.21429

此外,我们可以通过多种方式设置列名。

# set_names with magrittr
mtcars %>% 
  group_by(cyl) %>%
  summarise(mean(disp), mean(hp)) %>%
  magrittr::set_names(c("cyl", "disp_mean", "hp_mean"))

# set_names with purrr
mtcars %>% 
  group_by(cyl) %>%
  summarise(mean(disp), mean(hp)) %>%
  purrr::set_names(c("cyl", "disp_mean", "hp_mean"))

# setNames with stats
mtcars %>%
  group_by(cyl) %>%
  summarise(mean(disp), mean(hp)) %>%
  stats::setNames(c("cyl", "disp_mean", "hp_mean"))

# A tibble: 3 × 3
# cyl disp_mean   hp_mean
# <dbl>     <dbl>     <dbl>
# 1     4  105.1364  82.63636
# 2     6  183.3143 122.28571
# 3     8  353.1000 209.21429

【讨论】:

    【解决方案2】:

    dplyr 中,有几种不同的方法可以重命名列。

    一种是使用rename()函数。在此示例中,您需要对summarise() 创建的名称进行反引号,因为它们是表达式。

    group_by(mtcars, cyl) %>%
        summarise(mean(disp), mean(hp)) %>%
        rename(disp_mean = `mean(disp)`, hp_mean = `mean(hp)`)
    #   cyl disp_mean   hp_mean
    # 1   4  105.1364  82.63636
    # 2   6  183.3143 122.28571
    # 3   8  353.1000 209.21429
    

    您也可以使用select()。这更容易一些,因为我们可以使用列号,而无需弄乱反引号。

    group_by(mtcars, cyl) %>%
        summarise(mean(disp), mean(hp)) %>%
        select(1, disp_mean = 2, hp_mean = 3)
    

    但是对于这个示例,最好的方法是执行 cmets 中提到的 @thelatemail,即返回一步并命名 summarise() 中的列。

    group_by(mtcars, cyl) %>%
        summarise(disp_mean = mean(disp), hp_mean = mean(hp))
    

    【讨论】:

      【解决方案3】:

      您可以使用colnames&lt;-setNames(感谢@David Arenburg)

      group_by(mtcars, cyl) %>%
        summarise(mean(disp), mean(hp)) %>%
        `colnames<-`(c("cyl", "disp_mean", "hp_mean"))
        # or
        # `names<-`(c("cyl", "disp_mean", "hp_mean"))
        # setNames(., c("cyl", "disp_mean", "hp_mean")) 
      
      #   cyl disp_mean   hp_mean
      # 1   4  105.1364  82.63636
      # 2   6  183.3143 122.28571
      # 3   8  353.1000 209.21429
      

      或从magrittr 中选择一个Alias (set_colnames):

      library(magrittr)
      group_by(mtcars, cyl) %>%
        summarise(mean(disp), mean(hp)) %>%
        set_colnames(c("cyl", "disp_mean", "hp_mean"))
      

      dplyr::rename 如果您只是(重新)命名许多列中的几个(它需要同时写入旧名称和新名称;请参阅@Richard Scriven 的回答),那么dplyr::rename 可能会更方便

      【讨论】:

      • 漂亮。我假设`foo&lt;-`() 语法适用于任何此类“替换”函数。
      • 第一个解决方案很有启发性,基本上让我大吃一惊!谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-09
      • 1970-01-01
      • 2017-12-30
      • 1970-01-01
      • 1970-01-01
      • 2018-07-30
      • 2020-01-17
      相关资源
      最近更新 更多