【问题标题】:R tibble: aggregating by row across specific columns, by column groupsR tibble:跨特定列按行聚合,按列组
【发布时间】:2019-06-06 04:56:56
【问题描述】:

我有测试患者的生物化合物水平的数据,这些患者根据服用的某些药物分为不同的组。也就是说,我们有:

  • 列:药物(或组)A、B 和 C,其中每组有 3 名患者(单独表示,其中 A 中的患者表示为 A1、A2、A3;B 中的患者表示为 B1、B2、B3 和等等。)
  • 行:我们正在监测生物化合物CoroninDystrophinTubulin(随机谷歌搜索的蛋白质名称)等等。

所以我们有一个tibble 类似(tibble 中的所有值都是浮点数):

| compound  | A1 | A2 | A3 | B1 ... C3|
|-----------|----|----|----|---- ... --|
| Coronin   |
| Dystrophin|
| Gloverin  |
| keratin   |
| Tubulin   |

对于每个化合物,我希望计算每个组的平均值,作为一个新列,如下所示:

| compound  | A1 | A2 | A3 | B1 ...C3| mean_A | mean_B | mean_C |
|-----------|-----|-----|-----|---- ... --|---------|---------|---------|
| Coronin   |  1  |  2  |  3  |     ...   |    2    |  ...              |
| Dystrophin|  4  |  5  |  6  |     ...   |    5    |  ...              |
| Gloverin  |  ...
| keratin   |
| Tubulin   |

执行此操作的代码是:

my_tibble <- my_tibble %>% 
  mutate(mean_A = rowMeans(select(., c("A1", "A2", "A3")))) %>%
  mutate(mean_B = rowMeans(select(., c("B1", "B2", "B3")))) %>%
  mutate(mean_C = rowMeans(select(., c("C1", "C2", "C3"))))

问题是:我希望能够动态输入组数,即 C、D、E 等...其中 column-to-group 是一个单独的用户输入小标题自己说:

| group_name | name1 | name2 | name3 |
|------------|-------|-------|-------|
|      A     |  A1   |  B2   |  C3   |
|      B     |  B1   |  B2   |  C3   |
...
and so on

如何根据用户指定的组数(以及相关的样本到组名称)迭代地添加 mutate 动词?

注意:组名“C”、“B”......等是任意的(例如,这些组可能被分配给该组的药物名称),所以我不会使用依赖于它们的字面名称为“A”、“B”等事实的迭代操作。

【问题讨论】:

  • 将你的数据重新排列成一个长而整齐的格式,然后你就可以做到dat %&gt;% group_by(compound, grp) %&gt;% summarise(meanval=mean(value))。否则,当您实际上有一个值列被多个分组列拆分时,您最终会得到乱码,试图对列组进行子集化。
  • 抱歉,g11 组患者列名称是否已经提供?或者你有办法创造它们吗?我不清楚是否只给出了 group_names G1 等,或者是否也给出了 g11 名称。特别是,如果 group_name 和将难以解决的患者编号之间没有分隔符(列 g123 是 G12 组的患者 3 还是 G1 组的患者 23?)
  • 没有患者“g()”有两个原因:在实践中,不可能同时测试 10 种药物,每种药物也不可能有 10 名患者(出于经济原因)。此外,在组和患者名称可能是代词的意义上,名称是任意的。即可以为这些组分配药物名称(例如“zyprexa”、“tamiflu”等……您可以将它们命名为“red”、“green”、“blue”等),并为每个患者指定一个唯一的序列号,用于在某些黑盒数据库模式中唯一标识它们。
  • 另外,组-患者列名是用户输入的,所以你可以任意生成自己的来回答问题。
  • 第二个小标题可以为问题中的组分配名称;如果可以将其用作通用解决方案,那么我将能够接受您的回答。这是因为可能没有逻辑将每个列名链接到它们的组名,因为记录保持一致性差,但肯定会有一个表列出属于每个组的所有列名。

标签: r tibble


【解决方案1】:

一个选项是按列名拆分,循环使用listsapply,获取rowMeans 并将其分配给3 个新列

nm1 <- substr(names(df1)[-1], 1, nchar(names(df1)[-1])-1)  
df1[paste0("mean_", toupper(unique(nm1)))] <- 
            sapply(split.default(df1[-1], nm1), rowMeans)

df1
#  compound g11 g12 g13 g21 g22 g23 g31 g32 g33  mean_G1  mean_G2  mean_G3
#1        A   7   3   9   8   8   1   3   7   2 6.333333 5.666667 4.000000
#2        B   3   8   8   1   2   5   1   1   4 6.333333 2.666667 2.000000
#3        C   8   6   7   5   1   4   3   6   3 7.000000 3.333333 4.000000
#4        D   7   9   8   5   5   6   8   7   6 8.000000 5.333333 7.000000
#5        E   2   4   1   5   2   6   6   1   3 2.333333 4.333333 3.333333

注意:这可以扩展到任意数量的组。唯一需要更改的是当前示例中用于创建列名的1:3

数据

set.seed(24)
df1 <- cbind(compound = LETTERS[1:5], as.data.frame(matrix(sample(1:9, 5 * 9,
      replace = TRUE), nrow = 5, ncol = 9, dimnames = list(NULL,
        paste0(rep(paste0("g", 1:3), each = 3), 1:3)))))



      

【讨论】:

  • 组名“G1”、“G2” ...等是任意的(例如,它们可能对应于该组的药物名称),所以我不会使用依赖于它们实际上被命名为“G1”、“G2”等这一事实的迭代操作。我已经更新了问题以反映这一点。
猜你喜欢
  • 2015-07-27
  • 2016-10-02
  • 1970-01-01
  • 2020-11-26
  • 1970-01-01
  • 2014-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多