用 R 中缺少的列名替换另一个数据框中的列名?

Replacing column names from another dataframe with missing column names in R?

我有两个数据集:

一个。看起来像这样的数据框:

        SpeciesA  SpeciesB  SpeciesC  SpeciesD  SpeciesE  SpeciesY SpeciesZ
Site1     1          0        4        6          2        5        2
Site2     1          0        4        6          2        5        3
Site3     1          0        4        6          2        5        4
Site4     1          0        4        6          2        5        5

(注意:行值不相同,这里只是为了表示)

b。另一个数据集如下所示:

Order          Species
Order1         SpeciesA
Order1         SpeciesB
Order2         SpeciesC
Order2         SpeciesD
Order3         SpeciesE

请注意,某些物种(例如 SpeciesZ、SpeciesY)在 (b) 中没有相应的 "Order"。

我想将数据集 (2) 中的 Order 列与数据框 (1) 中相应的 Species 相匹配,并在同一 Order 下将值(如果有多个物种)相加。当物种(eg.SpeciesY,SpeciesZ)没有对应的Order时,我想将列重命名为NULL,然后将其删除(注意我需要这两个步骤)

预最终输出

         Order1    Order1   Order3    NULL   NULL
Site1     1          10       2        5     2
Site2     1          10       2        5     3
Site3     1          10       2        5     4
Site4     1          10       2        5     5

最终输出

         Order1      Order2    Order3   
Site1     1             10          2                
Site2     1             10          2                    
Site3     1             10          2                    
Site4     1             10          2            

这是问题 的扩展,其中大部分代码使用 dplyrmelt/reshape 函数。但是,我发现很难为此执行相同的分析,因为它会吐出一个错误,指出某些物种没有相应的值

一种方法是使用 match 创建索引,split 使用 Order 列的数据集子集,遍历 list 元素并获得 rowSums

i1 <- match(colnames(df1), df2$Species, nomatch = 0)
data.frame(lapply(split.default(df1[i1], df2$Order[i1]), rowSums))
#      Order1 Order2 Order3
#Site1      1     10      2
#Site2      1     10      2
#Site3      1     10      2
#Site4      1     10      2

或者我们可以将第一个数据集转换为 'long' 格式,与第二个数据集连接,按列分组,获取值列的 sum 并将其重新整形为 'wide'

library(tidyverse)
rownames_to_column(df1, "rn") %>%
      gather(Species, Val, -rn) %>% 
      left_join(., df2, by = "Species") %>%
      na.omit() %>%
      group_by(rn, Order) %>% 
      summarise(Val = sum(Val))  %>%
      spread(Order, Val)