【问题标题】:How can I use mutate to create columns named in a vector?如何使用 mutate 创建以向量命名的列?
【发布时间】:2023-04-09 16:32:02
【问题描述】:

我有一个tibble,我想使用字符向量向它添加列。向量的名称将是新列的名称,新列应填充向量的值(每行重复)。使用 for 循环很容易做到这一点,但我试图了解 across 的工作原理,但遇到了两个问题。

cv <- c("a"="x", "b"="y", "c"="z")  
tib <- tibble(c1=1:5)
myf <- function(x) { cv[x]}
tib %>% mutate(across(all_of(names(cv))), myf)  ## first problem
#   Error: Problem with `mutate()` input `..1`.
#   x Can't subset columns that don't exist.
#   x Columns `a`, `b`, and `c` don't exist.
tib %>% mutate_at(all_of(names(cv)), myf)
# ℹ Input `..1` is `across(all_of(names(cv)))`.

for (x in names(cv)) { ## do it with a for loop
  tib[[x]] <- myf(x)
}
tib %>% mutate(across(all_of(names(cv)), myf)) ## second problem

产生:

# A tibble: 5 x 4
     c1 a     b     c    
  <int> <chr> <chr> <chr>
1     1 NA    NA    NA   
2     2 NA    NA    NA   
3     3 NA    NA    NA   
4     4 NA    NA    NA   
5     5 NA    NA    NA   

tib %&gt;% mutate_at(all_of(names(cv)), myf) 替换最后一行会产生同样的错误行为。

第一个问题是mutate across 似乎不喜欢创建新列,原因我无法理解。第二个问题是across 不知道如何处理myf。它似乎想要某种我不知道如何创建的闭包。 (与mutate_at 相同。)我简要地查看了rlang,但无法确定如何将常规函数转换为适当类型的对象。

【问题讨论】:

  • across 用于循环已经存在的列
  • @akrun 解释了错误,但它让我不确定mutate 是否可以做到这一点
  • @akrun 我已经更新了问题以反映mutate_at 没有解决任何一个问题
  • mutate_atmutateacross 的前身。行为是循环现有的列。如果您需要创建新列,请使用循环或 map

标签: r dplyr tibble across


【解决方案1】:

across 可以在数据集中存在列时使用,如果我们想要更新这些列或通过指定 .names 从该列创建新列来更改列名。在这里,一种方法是使用map 循环名称,使用transmute 创建列并将这些列与原始数据绑定

library(purrr)
library(dplyr)
map_dfc(names(cv), ~ tib %>%
                     transmute(!! .x := myf(.x))) %>%
       bind_cols(tib, .)

-输出

# A tibble: 5 x 4
#     c1 a     b     c    
#  <int> <chr> <chr> <chr>
#1     1 x     y     z    
#2     2 x     y     z    
#3     3 x     y     z    
#4     4 x     y     z    
#5     5 x     y     z    

【讨论】:

  • 我可以把这个map_dfc 解决方案放在一系列管道中,例如tib %&gt;% do_stuff %&gt;% map_dfc(...)?
  • @flies 是的,你可以这样做,即names(cv) %&gt;% map_dfc(~ tib %&gt;% transmute(!! .x := myf(.x))) %&gt;% bind_cols(tib, .)
猜你喜欢
  • 2021-10-27
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 2018-10-03
  • 2018-08-26
  • 2018-08-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多