【问题标题】:Apply difference and mean between groups within a column R在列 R 中的组之间应用差异和均值
【发布时间】:2021-10-05 12:12:38
【问题描述】:

我有一个这样的数据框:

df = data.frame("subjectID" = c("S1","S2","S2","S1","S1","S2","S2","S1","S1","S2","S1","S2"), "treatment" = c("none","none","none","none","drug1","drug1","drug1","drug1","drug2","drug2","drug2","drug2"), "protein" = c("proteinA","proteinA","proteinB","proteinB","proteinA","proteinA","proteinB","proteinB","proteinA","proteinA","proteinB","proteinB"), "value"= c(5.3,4.3,4.5,2.3,6.5,5.4,1.2,3.2,2.3,4.5,6.5,3.4))

   subjectID treatment  protein value
1         S1      none proteinA   5.3
2         S2      none proteinA   4.3
3         S2      none proteinB   4.5
4         S1      none proteinB   2.3
5         S1     drug1 proteinA   6.5
6         S2     drug1 proteinA   5.4
7         S2     drug1 proteinB   1.2
8         S1     drug1 proteinB   3.2
9         S1     drug2 proteinA   2.3
10        S2     drug2 proteinA   4.5
11        S1     drug2 proteinB   6.5
12        S2     drug2 proteinB   3.4

我必须对此数据框进行以下计算:

  1. 找出每个受试者的每种蛋白质的治疗 =“药物 1”和治疗 =“无”之间的差异。

所以基本上对于一个单一的计算它会是:

diff = df$value[df$subjectID == "S1" & df$treatment == "drug1" & df$protein == "proteinA"] - df$value[df$subjectID == "S1" & df$treatment == "none" & df$protein == "proteinA"] 
diff 
> 1.2 

在上述示例中,值 6.5 - 5.3 给出了处理过的药物和未处理过的蛋白质 A 样本之间的差异。我同样对 S2 和 proteinA、S1/proteinB 和 S2/proteinB 重复此操作。

  1. 找出受试者之间的平均差异。

我的原始数据有 5 个不同的受试者、10 种不同的治疗方法(包括治疗 ==“无”)和 100 种蛋白质,我不可能手动为每个分组执行此操作。我将不得不计算每种药物治疗和未治疗之间的平均差异(9 种不同的药物治疗与未治疗)。

想要的输出可能是这样的:

 resdf
   protein drug1_mean_diff drug2_mean_diff
1 proteinA             1.15            -1.4
2 proteinB             -1.2            1.55

我最终应该有 100 个蛋白质(行)和 9 个均值差(列)

希望这很清楚。

谢谢!

【问题讨论】:

  • 您能否更新您的 MRE 以考虑新的约束(应将多个治疗都与无治疗进行比较)。?
  • 按要求更新
  • 您确定您的预期输出值正确吗?我无法复制它们...

标签: r dplyr tidyr


【解决方案1】:
library(tidyverse)

df <- data.frame(
  "subjectID" = c("S1", "S2", "S2", "S1", "S1", "S2", "S2", "S1", "S1", "S2", "S1", "S2"),
  "treatment" = c("none", "none", "none", "none", "drug1", "drug1", "drug1", "drug1", "drug2", "drug2", "drug2", "drug2"),
  "protein" = c("proteinA", "proteinA", "proteinB", "proteinB", "proteinA", "proteinA", "proteinB", "proteinB", "proteinA", "proteinA", "proteinB", "proteinB"),
  "value" = c(5.3, 4.3, 4.5, 2.3, 6.5, 5.4, 1.2, 3.2, 2.3, 4.5, 6.5, 3.4)
)

# For every pair of protein and drug treatment
expand_grid(
  protein = df$protein %>% unique(),
  comparison = df$treatment %>% unique() %>% setdiff("none")
) %>%
  mutate(
    mean_diff = comparison %>% map2_dbl(protein, ~ {
      df %>%
        pivot_wider(names_from = treatment, values_from = value) %>%
        filter(protein == .y) %>%
        rename_at(.x, ~"drug") %>%
        mutate(diff = none - drug) %>%
        pull(diff) %>%
        mean()
    })
  ) %>%
  pivot_wider(names_from = comparison, values_from = mean_diff, names_prefix = "mean_diff_")
#> # A tibble: 2 x 3
#>   protein  mean_diff_drug1 mean_diff_drug2
#>   <chr>              <dbl>           <dbl>
#> 1 proteinA           -1.15            1.4 
#> 2 proteinB            1.2            -1.55

reprex package (v2.0.1) 于 2021-10-05 创建

【讨论】:

  • 治疗:药物2 - 治疗:无,治疗:药物3 - 治疗:无等怎么样?
  • drug2 在我写这个答案时不是你的例子的一部分......等待几分钟
  • 它始终是问题主体的一部分。另外,我不是问题的作者;)
  • 我修改了我的答案。我也无法重现示例结果,但差异与@dario 相同(他只是吸毒 - 没有,我以相反的方式做,因此有不同的标志)
  • 嗨@danlooo,非常感谢您的回答。它适用于 MRE,但实际上,我可能有也可能没有所有药物的“药物”前缀。这是我在与您的代码一起使用时可能必须添加的内容。
【解决方案2】:

不知何故,我无法重现问题中显示的预期输出。但是,我认为这段代码应该给出想要的答案。但我可能弄错了或误解了什么。所以请在使用代码前检查:

  df = data.frame(subjectID = c("S1","S2","S2","S1","S1","S2","S2","S1","S1","S2","S1","S2"), 
                  treatment = c("none","none","none","none","drug1","drug1","drug1","drug1","drug2","drug2","drug2","drug2"),
                  protein = c("proteinA","proteinA","proteinB","proteinB","proteinA","proteinA","proteinB","proteinB","proteinA","proteinA","proteinB","proteinB"),
                  value = c(5.3,4.3,4.5,2.3,6.5,5.4,1.2,3.2,2.3,4.5,6.5,3.4))
  
  
  df %>% 
     filter(treatment != "none") %>% 
     left_join(df %>% filter(treatment == "none") %>% rename(control = value) %>% select(subjectID, protein, control)) %>% 
     mutate(diff = value - control) %>% 
     select(subjectID, protein, treatment, diff) %>% 
     pivot_wider(names_from = treatment, values_from = diff, names_prefix = "diff_") %>% 
     group_by(protein) %>% 
       summarise(across(starts_with("diff"), mean, rm.na=TRUE))
  

返回:

    protein  diff_drug1 diff_drug2
    <chr>         <dbl>      <dbl>
  1 proteinA       1.15      -1.4 
  2 proteinB      -1.20       1.55

【讨论】:

  • 嗨达里奥!是的,我编辑了预期的输出。对不起这是我的错。非常感谢您的帮助!
猜你喜欢
  • 2013-03-05
  • 1970-01-01
  • 2021-11-15
  • 2015-01-09
  • 2018-05-23
  • 1970-01-01
  • 1970-01-01
  • 2018-04-26
相关资源
最近更新 更多