【问题标题】:Can we create/mutate several new columns at once in tidyverse [duplicate]我们可以在 tidyverse 中一次创建/改变几个新列吗?
【发布时间】:2021-03-30 04:37:51
【问题描述】:

让我澄清一下,我在这里看的不是mutate_at 或mutate(across(..., ...)) 类型的语法。我只想知道如何在 tidyverse 管道语法中一次创建几个新列。

让我们假设iris 数据集的情况。

我想创建 10 个(或 100 个或更多)具有此类条件的新列。

  • 第一个新列(变量)说V1 只是Petal.Length * 1,
  • 第二个新列说V2 是Petal.Length * 2
  • 等等直到说V10Petal.Length * 10

没有为这些列中的每一个明确编写名称和公式,如果我想创建 100 个新列,这可能会很麻烦。

【问题讨论】:

  • 非常有帮助的问答。

标签: r tidyverse purrr


【解决方案1】:

你可以使用map函数:

library(dplyr)
library(purrr)

df <- iris %>% head
value <- 1:5

bind_cols(df, 
     map_dfc(value, ~df %>% transmute(!!paste0('col', .x) := Petal.Length * .x)))

#  Sepal.Length Sepal.Width Petal.Length Petal.Width Species col1 col2 col3 col4 col5
#1          5.1         3.5          1.4         0.2  setosa  1.4  2.8  4.2  5.6  7.0
#2          4.9         3.0          1.4         0.2  setosa  1.4  2.8  4.2  5.6  7.0
#3          4.7         3.2          1.3         0.2  setosa  1.3  2.6  3.9  5.2  6.5
#4          4.6         3.1          1.5         0.2  setosa  1.5  3.0  4.5  6.0  7.5
#5          5.0         3.6          1.4         0.2  setosa  1.4  2.8  4.2  5.6  7.0
#6          5.4         3.9          1.7         0.4  setosa  1.7  3.4  5.1  6.8  8.5

在基础 R 中,这可以通过 lapply 来完成:

df[paste0('col', value)] <- lapply(value, `*`, df$Petal.Length)

【讨论】:

  • 如果我们迭代地创建对象的名字,我们必须使用:=吗?
  • 是的,如果列名依赖于循环中的值和/或者是一个字符串,我们必须使用:=。
  • 还有一个问题@Ronak,!!在这里有什么用?为什么mutate 不在这里工作?我试过了,但它太混乱了
  • 1. !! 用于在 LHS 上具有可变列名。请参阅此示例 k &lt;- "n" 并检查 df %&gt;% mutate(k = 1) 与 df %&gt;% mutate(!!k := 1) 中新列名称的名称。 2.mutate 在这里也可以工作,但是使用mutate,您可以将整个数据框与新列一起返回,当我们将其与map_dfc 结合时,所有列都会重复,这不是我们需要的。 transmute 在每次迭代中只返回一列。
  • 很好地解释了@Ronak。
猜你喜欢
  • 2019-11-28
  • 1970-01-01
  • 1970-01-01
  • 2020-06-25
  • 2012-11-17
  • 1970-01-01
  • 2022-01-24
  • 2018-07-14
  • 1970-01-01
相关资源
最近更新 更多