可能是一个简单的。
我有这种类型的data.frame
:
df <- data.frame(sp1.name = c("sp1.n1",NA,"sp1.n3",NA), sp1.id = c("sp1.id1","sp1.id2",NA,NA),
sp2.name = c(NA,NA,"sp2.n3",NA), sp2.id = c(NA,NA,NA,"sp2.id4"),
sp3.name = c("sp3.n1",NA,NA,NA), sp3.id = c("sp3.id1",NA,NA,NA))
它由每个“sp”索引的成对列组成:sp<index>.name
和sp<index>.id
。在此示例中,索引为 1,2,3。
我正在寻找一种方法(可能通过 tidyverse
)来合并每个 sp
,其对应的 name 和 id 列对,其中合并规则为:
-
if !is.na(sp<index>.name) & !is.na(sp<index>.id) return sp<index>.name
-
if !is.na(sp<index>.name) & is.na(sp<index>.id) return sp<index>.name
-
else if is.na(sp<index>.name) & !is.na(sp<index>.id) return sp<index>.id
-
else return NA
因此,对于此示例,结果 data.frame
是:
df <- data.frame(sp1 = c("sp1.n1","sp1.id2","sp1.n3",NA),
sp2 = c(NA,NA,"sp2.n3","sp2.id4"),
sp3 = c("sp3.n1",NA,NA,NA))
最佳答案
你可以这样做:
library(tidyverse)
df %>%
mutate(rn = row_number()) %>%
gather(id, value, -rn) %>%
mutate(idx = gsub("\\..*", "", id)) %>%
group_by(idx, rn) %>%
mutate(
value = case_when(
any(grepl("name", id) & !is.na(value)) & any( (grepl("id", id) & !is.na(value)) | (grepl("id", id) & is.na(value)) ) ~ value[grepl("name", id)],
any(grepl("name", id) & is.na(value)) & any(grepl("id", id) & !is.na(value)) ~ value[grepl("id", id)],
TRUE ~ NA_character_)) %>%
distinct(idx, value, rn) %>%
spread(idx, value)
给予:
# A tibble: 4 x 4
# Groups: rn [4]
rn sp1 sp2 sp3
<int> <chr> <chr> <chr>
1 1 sp1.n1 NA sp3.n1
2 2 sp1.id2 NA NA
3 3 sp1.n3 sp2.n3 NA
4 4 NA sp2.id4 NA
关于r - 合并数据框列集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54382142/