我处理了与以下示例相对应的两个数据框:
# Data sets
set.seed(1)
dta_a <- data.frame(some_value = runif(n = 10),
identifier=c("A0001","A0002","A0003","A0004","A0005",
"A0006","B0001","B0002","B0003","B0004"),
other_val = runif(n = 10))
dta_b <- data.frame(variable_abc = runif(n = 6),
identifier=c("A0001","A0002","A0003,A0004,A0005,C0001",
"B0001,B0002","B0003","B0004"),
variable_df = runif(n = 6))
我想合并这两个数据帧并获得类似于下面所示的数据框:
结果数据框具有以下特性:
merge
命令与all.y = TRUE
和all.x = FALSE
一起执行,假设y
为{{1} }}。dta_b
获取第一个匹配的值,并忽略其余值。如果第一个标识符(dta_a
)上没有匹配项,我希望命令尝试匹配下一个标识符(A0003
)。我引用了A0004
命令,但自然地,merge
和其他解决方案都没问题。
答案 0 :(得分:3)
你可以'融化'dta_b,以便每个标识符有一行带有首选项顺序,然后加入所有标识符:
library(dplyr)
library(tidyr)
melt_dta_b = lapply(1:nrow(dta_b), function(i){
split_identifier = strsplit(as.character(dta_b$identifier[i]), split = ",", fixed = TRUE)[[1]]
data_frame(identifier = split_identifier,
original_identifier = dta_b$identifier[i], original_row = i, preference = 1:length(identifier),
variable_abc = dta_b$variable_abc[i], variable_df = dta_b$variable_df[i])
})
melt_dta_b = rbind_all(melt_dta_b)
此时,您只能选择具有最高优先级分数的那个:
joined_df = left_join(melt_dta_b, dta_a) %>%
filter(!is.na(some_value)) %>%
group_by(original_row) %>%
filter(preference == min(preference)) %>%
ungroup()
更新
为了不按名称显式调用变量,您可以使用以下代码绑定原始df的所有“未使用”列:
melt_dta_b = lapply(1:nrow(dta_b), function(i){
tmp = dta_b[i,]
split_identifier = strsplit(as.character(tmp$identifier), split = ",", fixed = TRUE)[[1]]
colnames(tmp)[2] = "original_identifier"
data_frame(identifier = split_identifier, original_row = i, preference = 1:length(identifier)) %>%
cbind(tmp)
})
melt_dta_b = rbind_all(melt_dta_b)
答案 1 :(得分:1)
只是这样做的一种方式,但不是我想的最佳方式。刚试了一下。 拆分标识符并根据第一个进行合并。
dta_a$identifier = as.vector(dta_a$identifier)
dta_a1 = data.frame(dta_a, identifier_split = do.call(rbind, strsplit(dta_a$identifier, split = ",", fixed = T)))
dta_b$identifier = as.vector(dta_b$identifier)
dta_b1 = data.frame(dta_b, identifier_split = do.call(rbind, strsplit(dta_b$identifier, split = ",", fixed = T)))
dta_join = merge(dta_a1, dta_b1, by = "identifier_split.1", all.x = F, all.y = T)
如果你没有匹配第一个,你会看到NAs,你可以将它们分组并与第二个合并(&#34; identifier_split.2&#34;)