![](/img/trans.png)
[英]How can i merge two data frames in R by the same values in different columns using base or dplyr?
[英]How to merge row data for two different columns in dplyr R?
site <- c(1,1,2,2,3,3,4,4)
rep <- c(1,2,1,2,1,2,1,2)
sp.1 <- c(NA,1,NA,4,NA,6,7,NA)
sp.2 <- c(2,NA,1,NA,5,6,7,8)
df.dummy <- data.frame(site, rep, sp.1, sp.2)
site rep sp.1 sp.2
1 1 1 NA 2
2 1 2 1 NA
3 2 1 NA 1
4 2 2 4 NA
5 3 1 NA 5
6 3 2 6 6
7 4 1 7 7
8 4 2 NA 8
在我的数据集中,我想做一些事情:在相同的站点,但不同的代表在一行中有 sp.1 的 NA,在另一行中有 sp.2 的 NA,反之亦然(例如,此数据框中的前两行) ,然后合并该列。
所以行应该像
site rep sp.1 sp.2
1 1 1 1 2
2 1 2 1 NA ---> get rid of this row
3 2 1 4 1
4 2 2 4 NA ---> get rid of this row
5 3 1 NA 5
6 3 2 6 6
7 4 1 7 7
8 4 2 NA 8
例如,如果 sp.2 有两个数据点用于相同的站点和代表(例如 5 和 6),则取这两个点的平均值并按 (1) 中的方式进行
最后,我只需要 4 行,但都充满了 sp.1 和 sp.2
site rep sp.1 sp.2
1 1 1 2
2 1 4 1
3 2 6 5.5
4 1 7 7.5
编辑:我添加了结果
根据澄清进行编辑:
library(tidyverse)
df.dummy %>%
pivot_longer(sp.1:sp.2) %>%
group_by(site, name) %>%
summarize(value = mean(value, na.rm = TRUE), .groups = "drop") %>%
pivot_wider(names_from = name, values_from = value)
或者更简单地说:
df.dummy %>%
group_by(site) %>%
summarize(across(sp.1:sp.2, ~mean(.x, na.rm = TRUE)))
# A tibble: 4 x 3
site sp.1 sp.2
<dbl> <dbl> <dbl>
1 1 1 2
2 2 4 1
3 3 6 5.5
4 4 7 7.5
或许,我们需要
library(dplyr)
df.dummy %>%
group_by(site) %>%
mutate(across(starts_with('sp'),
~.[order(is.na(.))])) %>%
filter(!if_all(starts_with('sp'), is.na)) %>%
summarise(rep= first(rep), across(starts_with('sp'),
mean, na.rm = TRUE))
-输出
# A tibble: 4 × 4
site rep sp.1 sp.2
<dbl> <dbl> <dbl> <dbl>
1 1 1 1 2
2 2 1 4 1
3 3 1 6 5.5
4 4 1 7 7.5
更新:保留rep
列的较短版本:
df.dummy %>%
group_by(site, first(rep)) %>%
summarize(across(sp.1:sp.2, ~mean(.x, na.rm = TRUE)))
第一个答案:我们可以这样做:按first(rep)
分组:
library(dplyr)
df.dummy %>%
group_by(site, first(rep)) %>%
summarise(sp.1=mean(sp.1, na.rm = TRUE), sp.2=mean(sp.2, na.rm = TRUE))
# Groups: site [4]
site `first(rep)` sp.1 sp.2
<dbl> <dbl> <dbl> <dbl>
1 1 1 1 2
2 2 1 4 1
3 3 1 6 5.5
4 4 1 7 7.5
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.