R-根据列名称将列添加到一起

R-根据列名称将列添加到一起,r,dataframe,plyr,melt,R,Dataframe,Plyr,Melt,我有一个数据框(df1),其中包括每个样本中不同物种的丰度: > SampleID Sp1 Sp2 Sp3 Sp4 ... Spn > asb-001 3 0 0 23 9 > asb-002 4 15 10 56 98 > asb-003 8 45 8 453 0 > asb-004 0 5

我有一个数据框(df1),其中包括每个样本中不同物种的丰度:

> SampleID   Sp1   Sp2   Sp3   Sp4   ... Spn
> asb-001      3     0     0    23         9
> asb-002      4    15    10    56        98
> asb-003      8    45     8   453         0
> asb-004      0     5     0     3         6
> asb-005    120    56     0     0         0
...
每列代表不同的物种

我有另一个数据帧(df2)

家族名称比物种名称少

我想根据物种名称将列添加到一起,以获得该科的总数(例如Sp1+Sp3+Sp6=Fam1)。我不想保留物种名称的原始列

如果一切按计划进行,我的新数据帧(df3)将如下所示:

> SampleID  Fam1  Fam2  Fam3 
> asb-001     12     0     9 
> asb-002     14    18   112 
> asb-003     28    58    18
> asb-004     10    12    10
> asb-005    142    65     0
...

我可以手动浏览并将单个物种添加到一起,但对于大型数据集来说,这似乎很乏味,而且可能会产生错误。我觉得我应该融化df1,但我对细节没有信心。任何建议都将不胜感激

将原始数据更改为长格式,并根据物种族映射加入。然后,您可以使用
group\u by
计算每个族的总和。最后,将数据以宽幅格式展开

library( tidyverse )

df1 %>% gather( Sp, Value, -SampleID ) %>%     # Convert to long format
  inner_join( df2 ) %>%                        # Combine with family mapping
  group_by( SampleID, Fam ) %>%                # Work on each sample/family pair
  summarize( ValSum = sum(Value) ) %>%         # Compute the sum across species
  ungroup %>% spread( Fam, ValSum, fill=0 )    # Convert back to wide format

根据每个样本是否在每个族中表示,在转换回宽格式后,您可能会得到
NA
。可选参数
fill=0
负责将这些
NA
转换为0。

将原始数据更改为长格式,并根据物种族映射进行合并。然后,您可以使用
group\u by
计算每个族的总和。最后,将数据以宽幅格式展开

library( tidyverse )

df1 %>% gather( Sp, Value, -SampleID ) %>%     # Convert to long format
  inner_join( df2 ) %>%                        # Combine with family mapping
  group_by( SampleID, Fam ) %>%                # Work on each sample/family pair
  summarize( ValSum = sum(Value) ) %>%         # Compute the sum across species
  ungroup %>% spread( Fam, ValSum, fill=0 )    # Convert back to wide format

根据每个样本是否在每个族中表示,在转换回宽格式后,您可能会得到
NA
。可选参数
fill=0
负责将这些
NA
转换为0。

另一种方法是使用
库(data.table)


另一种方法是使用
库(data.table)


您可能希望
收集
df1,然后在
Sp
上执行左连接。从类似的
tidyr::gather(df1,key='Sp',value='value',2:n)%%>%dplyr::left_join(df1,df2,by='Sp')
开始。您可能希望
gather
df1,然后在
Sp
上执行左连接。从类似于
tidyr::gather(df1,key='Sp',value='value',2:n)%%>%dplyr::left_join(df1,df2,by='Sp')的内容开始。
setDT(df1); setDT(df2) # Convert data.frames into data.tables

x = df2[melt(df1, variable.name = 'Sp'), on = 'Sp'] # Join melted df1 to df2 on species
df3 = dcast(x, SampleID~Fam, fun.aggregate = sum) # cast to wide format by summing total values per family