用 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
这是问题 的扩展,其中大部分代码使用 dplyr
或 melt
/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)
我有两个数据集:
一个。看起来像这样的数据框:
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
这是问题 dplyr
或 melt
/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)