结合select和mutate

时间:2017-04-12 16:39:26

标签: r dplyr

通常,我发现自己在dplyr中手动组合select()和mutate()函数。这通常是因为我正在整理数据框,想要根据旧列创建新列,并且只想保留新列。

例如,如果我有关于高度和宽度的数据但只是想用它们来计算并保留该区域,那么我会使用:

library(dplyr)
df <- data.frame(height = 1:3, width = 10:12)

df %>% 
  mutate(area = height * width) %>% 
  select(area)

当在mutate步骤中创建了许多变量时,可能很难确保它们都在选择步骤中。有没有更优雅的方法来保留mutate步骤中定义的变量?

我一直在使用的一个解决方法如下:

df %>%
  mutate(id = row_number()) %>%
  group_by(id) %>%
  summarise(area = height * width) %>%
  ungroup() %>%
  select(-id)

这有效,但非常冗长,使用summarize()意味着性能受到影响:

library(microbenchmark)

microbenchmark(

  df %>% 
    mutate(area = height * width) %>% 
    select(area),

  df %>%
    mutate(id = row_number()) %>%
    group_by(id) %>%
    summarise(area = height * width) %>%
    ungroup() %>%
    select(-id)
)

输出:

      min       lq     mean   median       uq      max neval cld
  868.822  954.053 1258.328 1147.050 1363.251 4369.544   100  a 
 1897.396 1958.754 2319.545 2247.022 2549.124 4025.050   100   b

我认为还有另一种解决方法,您可以将原始数据框名称与新数据框名称进行比较并采用正确的补充,但也许有更好的方法?

我觉得我在dplyr文档中遗漏了一些非常明显的东西,所以如果这是微不足道的话,请道歉!

2 个答案:

答案 0 :(得分:1)

只需创建自己的功能,结合两个步骤:

mutate_only = function (.data, ...) {
    names = names(match.call(expand.dots = FALSE)$...)
    .data %>% mutate(...) %>% select(one_of(names))
}

这需要一些工作才能在标准评估中正常运行。不幸的是,dplyr API目前正在发展,因此我不知道在几周内对此的建议是什么。因此,我只想参考relevant documentation

答案 1 :(得分:0)

只是让@Nate的评论更具可见性,transmute()是行之有效的方法!根据其描述:

mutate() adds new variables and preserves existing; transmute() drops existing variables.