【问题标题】:Row Means based on Column Substring基于列子字符串的行均值
【发布时间】:2020-06-26 21:37:04
【问题描述】:

我有一个如下所示的数据框:

df <- data.frame("CB_1.1"=c(0,5,6,2), "CB_1.16"=c(1,5,3,6), "HC_2.11"=c(3,3,4,5), "HC_1.12"=c(2,3,4,5), "HC_1.13"=c(1,0,0,5))

> df
  CB_1.1 CB_1.16 HC_2.11 HC_1.12 HC_1.13
1      0       1       3       2       1
2      5       5       3       3       0
3      6       3       4       4       0
4      2       6       5       5       5

我想在“.”之前取共享列名子字符串的行的平均值。产生这样的数据框:

  CB_1 HC_2 HC_1
1  0.5    3  1.5
2  5.0    3  1.5
3  4.5    4  2.0
4  4.0    5  5.0

您会注意到HC_2.11 列的值保持不变,因为此数据框中没有其他列具有HC_2

任何帮助将不胜感激!

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    1) apply/tapply 对于每一行,使用名称前缀的 INDEX 和函数 mean 在其上使用 tapply。转置结果。没有使用任何包。

    prefix <- sub("\\..*", "", names(df))
    t(apply(df, 1, tapply, prefix, mean))
    

    给出这个矩阵(如果您需要数据框结果,请将其包装在 data.frame(...) 中):

         CB_1 HC_1 HC_2
    [1,]  0.5  1.5    3
    [2,]  5.0  1.5    3
    [3,]  4.5  2.0    4
    [4,]  4.0  5.0    5
    

    2) lm 运行指定的回归。公式中的 +0 表示不添加截距。系数的转置将是所需的矩阵m。在下一行使名称更好。 prefix 来自 (1)。没有使用任何包。

    m <- t(coef(lm(t(df) ~ prefix + 0)))
    colnames(m) <- sub("prefix", "", colnames(m))
    m
    

    给出这个矩阵

         CB_1 HC_1 HC_2
    [1,]  0.5  1.5    3
    [2,]  5.0  1.5    3
    [3,]  4.5  2.0    4
    [4,]  4.0  5.0    5
    

    这源于以下事实:(1) 模型矩阵 X 仅包含 1 和 0,并且 (2) 它的不同列是正交的。模型矩阵如下所示:

    X <- model.matrix(~ prefix + 0) # model matrix
    X
    

    给予:

      prefixCB_1 prefixHC_1 prefixHC_2
    1          1          0          0
    2          1          0          0
    3          0          0          1
    4          0          1          0
    5          0          1          0
    attr(,"assign")
    [1] 1 1 1
    attr(,"contrasts")
    attr(,"contrasts")$prefix
    [1] "contr.treatment"
    

    因为模型矩阵X 的列是正交的,所以dft(df) 的列)的特定行 y 的任何列对应的系数只是 sum(x * y) / sum(x * x),并且由于 x 是一个 0/​​1 向量,等于 y 的值的平均值,对应于 x 中的 1。

    3) stack/tapply 转换为长格式,同时插入id 列。然后使用tapply 转换回宽格式tapply-ing mean。没有使用任何包。

    long <- transform(stack(df), ind = sub("\\..*", "", ind), id = c(row(df)))    
    with(long, tapply(values, long[c("id", "ind")], mean))
    

    给这张桌子。如果你想要一个data.frame,把它包装在as.data.frame.matrix中。

       ind
    id  CB_1 HC_1 HC_2
      1  0.5  1.5    3
      2  5.0  1.5    3
      3  4.5  2.0    4
      4  4.0  5.0    5
    

    【讨论】:

    • 谢谢!为什么要在回归示例中添加 0?
    • 我只是对回归示例如何计算平均值感到困惑。
    • 已对 (2) 进行了说明。
    【解决方案2】:
    • 这是使用rowMeans + split.default 的基本 R 解决方案,即,
    dfout <- as.data.frame(Map(rowMeans, split.default(df,factor(s <- gsub("\\..*$","",names(df)), levels = unique(s)))))
    

    这样

    > dfout
      CB_1 HC_2 HC_1
    1  0.5    3  1.5
    2  5.0    3  1.5
    3  4.5    4  2.0
    4  4.0    5  5.0
    
    • 如果您不介意列名的顺序,可以使用下面较短的代码
    dfout <- as.data.frame(Map(rowMeans,split.default(df,gsub("\\..*$","",names(df)))))
    

    这样

    > dfout
      CB_1 HC_1 HC_2
    1  0.5  1.5    3
    2  5.0  1.5    3
    3  4.5  2.0    4
    4  4.0  5.0    5
    

    【讨论】:

      【解决方案3】:

      涉及dplyrpurrr 的选项可能是:

      map_dfc(.x = unique(sub("\\..*$", "", names(df))),
              ~ df %>%
               transmute(!!.x := rowMeans(select(., starts_with(.x)))))
      
        CB_1 HC_2 HC_1
      1  0.5    3  1.5
      2  5.0    3  1.5
      3  4.5    4  2.0
      4  4.0    5  5.0
      

      【讨论】:

        【解决方案4】:

        基本选项可以是:

        #find column names splitting on "."
        
        cols <- unique(sapply(strsplit(names(df),".", fixed = T), `[`, 1))
        
        #loop through each column name and find the rowMeans
        
        as.data.frame(sapply(cols, function (x) rowMeans(df[grep(x, names(df))])))
        
          CB_1 HC_2 HC_1
        1  0.5    3  1.5
        2  5.0    3  1.5
        3  4.5    4  2.0
        4  4.0    5  5.0
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-12-17
          • 2021-08-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-25
          • 1970-01-01
          • 2020-07-09
          相关资源
          最近更新 更多