【问题标题】:Calculate sub-column-wise z scores in R data.frame计算 R data.frame 中的子列 z 分数
【发布时间】:2020-08-09 04:44:50
【问题描述】:

我有下面的例子data.frame

df = data.frame(a=c(rep("a",8), rep("b",5), rep("c",7), rep("d",10)), 
    b=rnorm(30, 6, 2), 
    c=rnorm(30, 12, 3.5), 
    d=rnorm(30, 8, 3)
    )

对于每一列,我想计算 a 列中定义的每个子组的 z 分数。 This post 对我很有帮助,我现在可以使用以下方法来做到这一点:

 df$b.zscore <- ave(df$b, df$a, FUN = scale)
 df$c.zscore <- ave(df$c, df$a, FUN = scale)
 df$d.zscore <- ave(df$d, df$a, FUN = scale)

但我的真实数据有更多列。对于 b-d 列,是否有更优雅的方法来完成此操作?也许使用for 循环?请问我该怎么做?我希望任何人都可以提供帮助。谢谢。

【问题讨论】:

    标签: r dataframe matrix multiple-columns


    【解决方案1】:

    您可以在列上使用lapply

    cols <- c('b', 'c', 'd')
    new_cols <- paste0(cols, '_zscore')
    df[new_cols] <- lapply(df[cols], function(x) ave(x, df$a, FUN = scale))
    

    但是,这种对多列进行操作的操作最好使用dplyr

    library(dplyr)
    
    df %>%
      group_by(a) %>%
      mutate(across(b:d, list(zscore = ~as.numeric(scale(.)))))
      #For dplyr < 1.0.0
      #mutate_at(vars(b:d), list(zscore = ~as.numeric(scale(.))))
    

    data.table

    library(data.table)
    setDT(df)[, (new_cols) := lapply(.SD, function(x) as.numeric(scale(x))), a, 
                .SDcols = cols]
    

    【讨论】:

    • 这很棒。是否也可以按照上面的帖子将它们作为列添加到原始表中?那太棒了。
    • 您使用的是哪个答案? base Rdplyrdata.table ?
    • 没关系,你选择你喜欢的:)
    猜你喜欢
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 2020-07-23
    • 1970-01-01
    • 2022-08-14
    • 1970-01-01
    相关资源
    最近更新 更多