我想先通过一列将一个数据帧连接到另一个数据帧,然后,如果没有匹配"我想让它通过另一列连接起来。这个问题与这个问题类似,但我试图得到一个稍微不同的输出。
以下是我的"观察">
#my df
my_plants <- data.frame(scientific_name = c("Abelmoschus esculentus",
"Abies balsamea",
"Ammophila breviligulata",
"Zigadenus glaucus"),
percent_cover = c(90, 80, 10, 60))
,这里是main list
,我想从每个观察中提取一些数据。显然这是简化的。
#hypothetical database
plant_database <- data.frame(scientific_name = c("Abelmoschus esculentus",
"Abies balsamea",
"Ammophila breviligulata",
"Anticlea elegans"),
synonym = c(NA_character_,
NA_character_,
NA_character_,
"Zigadenus glaucus"),
score = c(1, 1, 2, 6))
这是一个将我的观察结果加入到主列表的函数。注意:我使用left_join是因为我想知道哪些观测值不匹配。
#joining function
joining_fun <- function(plants, database) {
database_long <- database %>%
dplyr::mutate(ID = row.names(.)) %>%
tidyr::pivot_longer(., cols = c(scientific_name, synonym),
values_to = "scientific_name")
join <- dplyr::left_join(plants, database_long, by = "scientific_name") %>%
dplyr::select(-name)
return(join)
}
让我在这里:
joining_fun(my_plants, plant_database)
scientific_name percent_cover score ID
1 Abelmoschus esculentus 90 1 1
2 Abies balsamea 80 1 2
3 Ammophila breviligulata 10 2 3
4 Zigadenus glaucus 60 6 4
但是我想要这样的:
scientific_name synonym percent_cover score ID
Abelmoschus esculentus NA 90 1 1
Abies balsamea NA 80 1 2
Ammophila breviligulata NA 10 2 3
Anticlea elegans Zigadenus glaucus 60 6 4
谢谢!
- 使用
inner_join()
创建只包含scientific_name
上匹配的情况的df - 使用
anti_join()
获取不匹配scientific_name
的plants
版本。 - 在这些不匹配的情况下,使用
"synonym" = "scientific_name"
键执行database
的另一个inner_join()
。 - 再做一个
anti_join()
来获得在任何一列中没有匹配的情况。 - 最后,将所有结果绑定在一起。
library(dplyr)
# add test case with no match in either column
my_plants <- add_row(
my_plants,
scientific_name = "Stackus overflovius",
percent_cover = 0
)
joining_fun <- function(plants, database) {
by_sci_name <- inner_join(plants, database, by = "scientific_name")
no_sci_match <- anti_join(plants, database, by = "scientific_name")
by_syn <- inner_join(database, no_sci_match, by = c("synonym" = "scientific_name"))
no_match <- anti_join(no_sci_match, database, by = c("scientific_name" = "synonym"))
bind_rows(by_syn, by_sci_name, no_match)
}
joining_fun(my_plants, plant_database)
scientific_name synonym score percent_cover
1 Anticlea elegans Zigadenus glaucus 6 60
2 Abelmoschus esculentus <NA> 1 90
3 Abies balsamea <NA> 1 80
4 Ammophila breviligulata <NA> 2 10
5 Stackus overflovius <NA> NA 0