基于灵活 subsetting/conditional 跨数据帧的 R 函数

R function across dataframe based on flexible subsetting/conditional

我在 R 中有以下示例数据框:

SampleID = c("A25", "A25", "A25", "A25", "A25", "A25", "A25", "A25", "A25", "A25", "A26", "A26", "A26", "A26", "A26", "A26", "A26", "A26", "A26", "A26")
MaterialID = c("DR1", "DR4", "DR9", "DR10", "DR12", "DR14", "DR15", "DR18", "DR23", "DR25", "DR3", "DR5", "DR9", "DR11", "DR12", "DR13", "DR15", "DR18", "DR23", "DR26")
Concentration = c(0.15, 0.02, 0.43, 0.56, 0.13, 1.2, 0.08, 0.03, 1.78, 0.65, 0.86, 0.04, 0.67, 1.2, 0.11, 0.04, 0.24, 0.08, 1.01, 0.95)
MyData = data.frame(SampleID, MaterialID, Concentration)

看起来像这样:

   SampleID MaterialID Concentration
1       A25        DR1          0.15
2       A25        DR4          0.02
3       A25        DR9          0.43
4       A25       DR10          0.56
5       A25       DR12          0.13
6       A25       DR14          1.20
7       A25       DR15          0.08
8       A25       DR18          0.03
9       A25       DR23          1.78
10      A25       DR25          0.65
11      A26        DR3          0.86
12      A26        DR5          0.04
13      A26        DR9          0.67
14      A26       DR11          1.20
15      A26       DR12          0.11
16      A26       DR13          0.04
17      A26       DR15          0.24
18      A26       DR18          0.08
19      A26       DR23          1.01
20      A26       DR26          0.95

我还有一个我特别感兴趣的 MaterialID 列表,存储在变量 MaterialID_sub.

MaterialID_sub = c("DR1", "DR4", "DR10", "DR12", "DR14", "DR18", "DR23", "DR28")

我想做以下事情:

如果 SampleIDMaterialID_sub 中指定的 8 个 MaterialIDs 中至少有 6 个,则对该样本的 MaterialID_sub 中 ID 的浓度求和,然后乘以2。例如,样品A25包含MaterialID_sub中8个ID中的7个,然后将这7个ID的浓度相加等于3.87,然后乘以2等于7.74。然而,示例 A26 没有至少 6 个 MaterialID_sub 中列出的 ID,因此不会被求和。

输出看起来像这样,其中只有满足上述条件的样本才会包含在输出中(例如 A25):

SampleID   Sum*2   
A25        7.74     
Etc.

请注意,我提供的示例只是包含数百个 SampleIDs 的更大数据集的一小部分,并且给定样本的 MaterialIDs 的实际数量要大得多。所以扩大规模很重要。如果有办法将此代码合并到 dplyr 管道中,那就太好了。这个问题的解决方案似乎超出了我对 R 的掌握范围,因为我迄今为止的尝试都失败了。

非常感谢任何建议,谢谢!

我们可以根据条件对'SampleID'、filter这些SampleID进行分组,即至少6个MaterialID应该与MaterialID_Sub匹配,并且只保留那些匹配的行,然后得到 'Concentration' 的 sum 并乘以 2

library(dplyr)
MyData %>% 
   group_by(SampleID) %>%
   filter(sum(MaterialID %in% MaterialID_sub)>=6,
           MaterialID %in% MaterialID_sub) %>% 
   summarise(Sum = sum(Concentration) * 2)

-输出

# A tibble: 1 x 2
# SampleID   Sum
#  <chr>    <dbl>
#1 A25       7.74