【问题标题】:Mutate each column with function with two parameter grouped by another column使用由另一列分组的两个参数对每一列进行变异
【发布时间】:2017-09-13 03:42:06
【问题描述】:

以下数据集代表我的情况:

library(dplyr)
df <- data_frame(
  G1 = rep(1:2, each = 10),
  G2 = rep(1:10, 2),
  C1 = rnorm(20),
  C2 = rnorm(20),
  C3 = rnorm(20),
  C4 = rnorm(20)
)

我要执行以下操作,

df %>%
  group_by(G1, G2) %>%
  mutate(
    C1 = C1 - C2,
    C2 = C2 - C2,
    C3 = C3 - C2,
    C4 = C4 - C2
  )

如果只有 4 列(C1、C2、C3 和 C4),我可以应用上述解决方案。但是,我有很多列,对于每一列,我都需要执行相同的操作。是否有任何简洁明了的解决方案可以将此问题扩展到许多列?

【问题讨论】:

    标签: r dplyr data-manipulation tidyr tidyverse


    【解决方案1】:

    如果您可以在希望改变的列名中找到一些共性,您可以利用dplyr::mutate_at()

    df %>%
        group_by(G1, G2) %>%
        mutate_at(vars(starts_with("C")), funs(. - C2))
    

    编辑

    因为mutate() 按顺序操作并存储每一列的结果,所以您有两种选择来解决这个问题。您可以使用reorder(df, everything(), C2),因此您的C2data.frame 中的最后一个,或者像这样添加第二行:

    set.seed(1)
    library(dplyr)
    df <- data_frame(
        G1 = rep(1:2, each = 10),
        G2 = rep(1:10, 2),
        C1 = rnorm(20, 0),
        C2 = rnorm(20, 1),
        C3 = rnorm(20, 10),
        C4 = rnorm(20, 100)
    )
    
    
    df %>%
        mutate_at(vars(starts_with("C"), -C2), funs(. - C2)) %>%
        mutate_at(vars(C2), funs(. - C2))
    

    这只是对除第一行的C2 之外的每一列进行变异。然后第二行返回并在其他列被愉快地减去之后改变C2

    【讨论】:

    • 非常好的答案,在我原来的情况下,在这种情况下我没有以“C”开头的列,如何选择除分组变量之外的所有变量?
    • 你可以调整为vars(-G1, -G2)
    • 好的,所以在这种情况下,我什至不需要进行分组。谢谢
    • 很抱歉,但这是行不通的。当我使用 (. - C2) 时,C3 和 C4 实际上会从 0 中减去,即 C2 - C2。请帮我找出替代解决方案。
    • @TheRimalaya 让我知道我的编辑是否可以恢复工作
    【解决方案2】:

    如何使用data.table 指定您想要的列和.SDcols

    library(data.table)
    cols <- colnames(df)[which(grepl("C",colnames(df)))]
    dt <- setDT(df)[, lapply(.SD, function(x) x - C2), by=.(G1,G2), .SDcols = cols]
    

    【讨论】:

    • 谢谢你的解决方案,我已经用data.table完成了。
    猜你喜欢
    • 2021-04-29
    • 2021-12-17
    • 2014-10-20
    • 2021-10-30
    • 2019-05-13
    • 2016-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多