R语言 合并选择和变异

64jmpszr  于 2023-06-19  发布在  其他
关注(0)|答案(3)|浏览(94)

我经常发现自己在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)

这是可行的,但相当冗长,并且summarise()的使用意味着有一个性能打击:

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文档中遗漏了一些非常明显的东西,所以如果这是微不足道的,我道歉!

nx7onnlm

nx7onnlm1#

只是为了给予更多的可见性@Nate的评论,transmute()是要走的路!!从它的描述来看:

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

编辑:为了给予工作示例,

df %>%
  transmute(area = height * width)

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

dsekswqp2#

只需创建您自己的函数,将这两个步骤结合起来:

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

这需要一些工作才能与标准评估一起正常运行。不幸的是,dplyr API目前正在这一点上发展,所以我不知道几周后对此的建议是什么。因此,我只引用relevant documentation

bnlyeluc

bnlyeluc3#

只需使用.keep参数:

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

df %>% 
  mutate(area = height * width,
         .keep = "none")

# area
# 1   10
# 2   22
# 3   36

更多选项包括:.keep = c("all", "used", "unused", "none")
有关完整描述,请参见:
控制在输出中保留.data中的哪些列。正在分组列和由...创建的列总是保留着。

  • “all”保留. data中的所有列。这是默认值。
  • “used”仅保留在…中使用的列以创建新的列。这对于检查您的工作非常有用,因为它并排显示输入和输出。
  • “未使用”只保留在……中未使用的列以创建新的列。如果您生成新列,但不再需要用于生成它们的列,则这很有用。
  • “none”不会保留.data中的任何额外列。只有由...创建的分组变量和列都保留了下来

相关问题