【问题标题】:Shortcut to calculate the mean of columns in a data frame计算数据框中列的平均值的快捷方式
【发布时间】:2021-11-26 01:46:41
【问题描述】:

我有以下数据框:

Gene <- c("1","2","3","4","5","6")
> A1.1 <- c(1,1,2,4,3,5)
> A1.2 <- c(1,2,3,4,5,6)
> B1.1 <- c(2,2,3,5,5,5)
> B1.2 <- c(1,2,3,5,5,5)
> A2.1 <- c(3,2,5,6,6,6)
> A2.2 <- c(1,1,2,2,4,6)
> B2.1 <- c(2,1,4,5,7,4)
> B2.2 <- c(1,3,4,5,2,3)
> df <- data.frame(Gene,A1.1,A1.2,B1.1,B1.2,A2.1,A2.2,B2.1,B2.2)
> df
  Gene A1.1 A1.2 B1.1 B1.2 A2.1 A2.2 B2.1 B2.2
1    1    1    1    2    1    3    1    2    1
2    2    1    2    2    2    2    1    1    3
3    3    2    3    3    3    5    2    4    4
4    4    4    4    5    5    6    2    5    5
5    5    3    5    5    5    6    4    7    2
6    6    5    6    5    5    6    6    4    3

我希望计算每个基因(行)相同字母/数字的样本(列)的平均值。

即。计算两个 A1 样本、两个 A2 样本、两个 B1 样本和两个 B2 样本的每个基因 (#1-6) 的平均值。

我知道我可以使用apply() 完成这项工作

前,

> A1_df <- data.frame(df$A1.1, df$A1.2)
> A1 <- apply(A1_df, 1, mean)
> A1
[1] 1.0 1.5 2.5 4.0 4.0 5.5

但是有没有使用sapply() 的快捷方式,这样我最终会得到一个新的数据框,其中列现在是“A1”、“A2”、“B1”、“B2”?

如果有什么不清楚的地方告诉我

谢谢

【问题讨论】:

    标签: r sapply


    【解决方案1】:

    在这里,我们可以在数字列上使用split.default,方法是删除列名中的. 及其后面的数字以拆分为data.frame 列表,然后使用@987654324 循环list @ 并通过rowMeans 获取mean

    sapply(split.default(df[-1], sub("\\.\\d+", "", names(df)[-1])), rowMeans)
    

    -输出

       A1  A2  B1  B2
    1 1.0 2.0 1.5 1.5
    2 1.5 1.5 2.0 2.0
    3 2.5 3.5 3.0 4.0
    4 4.0 4.0 5.0 5.0
    5 4.0 5.0 5.0 4.5
    6 5.5 6.0 5.0 3.5
    

    或使用pivot_longer 重塑为“长”格式,并按mean 分组。在这里,names_pattern 正在捕获 ((.*)) . 之前的字符和列名中的数字,这将以长格式创建的 .value

    library(dplyr)
    library(tidyr)
    df %>% 
       pivot_longer(cols = -Gene, names_to = ".value", 
          names_pattern = "(.*)\\.\\d+") %>%
       group_by(Gene) %>%
       summarise(across(everything(), mean))
    # A tibble: 6 × 5
       Gene    A1    B1    A2    B2
      <int> <dbl> <dbl> <dbl> <dbl>
    1     1   1     1.5   2     1.5
    2     2   1.5   2     1.5   2  
    3     3   2.5   3     3.5   4  
    4     4   4     5     4     5  
    5     5   4     5     5     4.5
    6     6   5.5   5     6     3.5
    

    数据

    df <- structure(list(Gene = 1:6, A1.1 = c(1L, 1L, 2L, 4L, 3L, 5L), 
        A1.2 = 1:6, B1.1 = c(2L, 2L, 3L, 5L, 5L, 5L), B1.2 = c(1L, 
        2L, 3L, 5L, 5L, 5L), A2.1 = c(3L, 2L, 5L, 6L, 6L, 6L), A2.2 = c(1L, 
        1L, 2L, 2L, 4L, 6L), B2.1 = c(2L, 1L, 4L, 5L, 7L, 4L), B2.2 = c(1L, 
        3L, 4L, 5L, 2L, 3L)), class = "data.frame", row.names = c("1", 
    "2", "3", "4", "5", "6"))
    

    【讨论】:

    • 代码效果很好,谢谢!
    猜你喜欢
    • 2016-03-03
    • 1970-01-01
    • 2016-09-16
    • 1970-01-01
    • 2020-10-20
    • 2021-12-12
    • 2017-07-07
    相关资源
    最近更新 更多