我有两个数据帧-test
和idx
-我的目标是使用merge()
或类似的函数进行条件连接。
例如,test
的ID具有多个可能的键(有些还包含NA值)。您不会为两个单独的ids
找到相同的键,这些键将始终是唯一的。
> test
id keyA keyB keyC
1 foo NA 2 10
2 bar 1 NA 6
3 baz 7 NA 4
4 li 8 3 NA
5 qux 9 NA NA
我的目标是加入idx
,其中密钥匹配,例如:
> idx
key value
1 2 NA
2 10 NA
3 7 NA
4 4 NA
5 9 NA
联接应输出:
> idx
key value
1 2 foo
2 10 foo
3 7 bar
4 4 bar
5 9 quz
我了解如何在一个或多个列上使用merge
,但不确定在涉及OR
语句时如何使用它(在这种情况下,匹配项将在keyA或keyB或keyC)
在R中如何执行此联接?
数据:
dput(test)
structure(list(id = c("foo", "bar", "baz", "li", "qux"), keyA = c(NA,
1, 7, 8, 9), keyB = c(2, NA, NA, 3, NA), keyC = c(10, 6, 4, NA,
NA)), row.names = c(NA, -5L), class = "data.frame")
dput(idx)
structure(list(key = c(2, 10, 7, 4, 9), value = c(NA, NA, NA,
NA, NA)), row.names = c(NA, -5L), class = "data.frame")
答案 0 :(得分:2)
我们可以gather
test
转换为长格式,然后left_join
library(dplyr)
library(tidyr)
idx %>%
left_join(test %>%
gather(key, value, -id, na.rm = TRUE), by = c("key" = "value")) %>%
select(key, id)
# key id
#1 2 foo
#2 10 foo
#3 7 baz
#4 4 baz
#5 9 qux
或者就像@David Arenburg提到的那样使用data.table
library(data.table)
melt(setDT(test), "id")[setDT(idx), on = .(value = key), .(key, id)]
答案 1 :(得分:2)
我不知道这是否是您要寻找的解决方案,但是您可以使用reshape2包中的melt函数通过融合测试data.frame来实现。
test <- structure(list(id = c("foo", "bar", "baz", "li", "qux"), keyA = c(NA,
1, 7, 8, 9), keyB = c(2, NA, NA, 3, NA), keyC = c(10, 6, 4, NA,
NA)), row.names = c(NA, -5L), class = "data.frame")
library(reshape2)
melted_test <- melt(test)
melted_test
Using id as id variables
id variable value
1 foo keyA NA
2 bar keyA 1
3 baz keyA 7
4 li keyA 8
5 qux keyA 9
6 foo keyB 2
7 bar keyB NA
8 baz keyB NA
9 li keyB 3
10 qux keyB NA
11 foo keyC 10
12 bar keyC 6
13 baz keyC 4
14 li keyC NA
15 qux keyC NA
然后,您只需要将idx和melted_test合并一次,并只保留所需的列即可。
答案 2 :(得分:2)
一种dplyr
解决方案可以是先到达left_join
,然后到达coalesce
:
library(dplyr)
test <- data.frame(id = c("foo", "bar", "baz", "li", "qux"), keyA = c(NA, 1, 7, 8, 9), keyB = c(2, NA, NA, 3, NA), keyC = c(10, 6, 4, NA, NA))
idx <- data.frame(key = c(2, 10, 7, 4, 9), value = c(NA, NA, NA, NA, NA))
idx <- left_join(idx, test[,c("keyA", "id")], by = c("key" = "keyA")) %>%
left_join(test[,c("keyB", "id")], by = c("key" = "keyB")) %>%
left_join(test[,c("keyC", "id")], by = c("key" = "keyC")) %>%
mutate(value = coalesce(id.x,id.y,id)) %>%
select(key, value)
答案 3 :(得分:1)
另一种方法:
library(tidyverse)
nest(test, -id) %>%
rowwise() %>%
mutate(key = list(idx$key[idx$key %in% data])) %>%
unnest(key, .drop = T) %>%
select(key, value = 'id')
# # A tibble: 5 x 2
# key value
# <int> <chr>
# 1 2 foo
# 2 10 foo
# 3 7 baz
# 4 4 baz
# 5 9 qux