r - 将数据框中的每一行与另一个数据框中的多行进行比较并获得结果
问题描述
我有 2 个数据集 df1 和 df2。
df1
c1 match c3 c4
AA1 AB cat dog
AA1 CD dfs abd
AA1 EF js hn
AA1 GH bsk jtd
AA2 AB cat mouse
AA2 CD adb mop
AA2 EF powas qwert
AA2 GH sms mms
AA3 AB i j
AA3 CD fgh ejk
AA3 EF mib loi
AA3 GH revit roger
df2
match d2 result
AB cat friendly
AB mouse enemy
CD dfs r1
CD adb r1
CD fgh r2
CD ejk r3
EF mib some_result
GH sms sent
GH mms sent
IJ xxx yyy
KL crt zzz
KL rrr qqq
我想通过“match”列匹配 df1 和 df2,并在 df1 中添加 2 个新列“result_c1”和“result_c2”。result_c1 从 df2 中得到对应的结果,首先匹配匹配列,然后将 df1 中的 c3 匹配到 df2 中的 d2。result_c2 从 df2 中得到对应的结果,首先匹配 match 列,然后将 df1 中的 c4 匹配到 df2 中的 d2。如果没有匹配,则返回“no_match”。有没有一种有效的方法来做到这一点?
result
c1 match c3 c4 result_c1 result_c2
AA1 AB cat dog friendly no_match
AA1 CD dfs adb r1 r1
AA1 EF js hn no_match no_match
AA1 GH bsk jtd no_match no_match
AA2 AB cat mouse friendly enemy
AA2 CD adb mop r1 no_match
AA2 EF powas qwert no_match no_match
AA2 GH sms mms sent sent
AA3 AB i j no_match no_match
AA3 CD fgh ejk r2 r3
AA3 EF mib loi some_result no_match
AA3 GH revit roger no_match no_match
数据附在下面:
df1 <- data.frame(list(c1 = c("AA1", "AA1", "AA1", "AA1", "AA2", "AA2", "AA2", "AA2",
"AA3", "AA3", "AA3", "AA3"), match = c("AB", "CD", "EF", "GH",
"AB", "CD", "EF", "GH",
"AB", "CD", "EF", "GH"),
c3 = c("cat", "dfs", "js", "bsk", "cat", "adb", "powas", "sms", "i",
"fgh", "mib", "revit"), c4 = c("dog", "abd", "hn", "jtd", "mouse",
"mop", "qwert", "mms", "j", "ejk", "loi", "roger")))
df2 <- data.frame(list(match = c("AB", "AB", "CD", "CD", "CD", "CD", "EF", "GH", "GH", "IJ", "KL", "KL"),
d2 = c("cat", "mouse", "dfs", "adb", "fgh", "ejk", "mib", "sms", "mms", "xxx", "crt", "rrr"),
result = c("friendly", "enemy", "r1", "r1", "r2", "r3", "some_result", "sent", "sent", "yyy", "zzz", "qqq")))
谢谢你。
解决方案
dplyr
使用自定义函数的一种方法
apply_fun <- function(x, y, r) {
inds <- x %in% y
if (any(inds)) r[match(x[which.max(inds)], y)] else "no_match"
}
library(dplyr)
df1 %>%
left_join(df2, by = "match") %>%
mutate_all(as.character) %>%
group_by(c1, match) %>%
summarise(result_c1 = apply_fun(c3, d2, result),
result_c2 = apply_fun(c4, d2, result))
# c1 match result_c1 result_c2
# <chr> <chr> <chr> <chr>
# 1 AA1 AB friendly no_match
# 2 AA1 CD r1 no_match
# 3 AA1 EF no_match no_match
# 4 AA1 GH no_match no_match
# 5 AA2 AB friendly enemy
# 6 AA2 CD r1 no_match
# 7 AA2 EF no_match no_match
# 8 AA2 GH sent sent
# 9 AA3 AB no_match no_match
#10 AA3 CD r2 r3
#11 AA3 EF some_result no_match
#12 AA3 GH no_match no_match
推荐阅读
- user-interface - 每当导航到该页面时,Xamarin 表单 Switch Toggled 事件都会自动触发
- python - try-finally 块:当 finally 块应该在 else 块之前运行时,为什么下面的代码可以工作?
- android - 安卓音频视图
- blazor - 将 Blazor 组件移动到共享组件项目
- python - DataFrame 转 JSON 格式,使用列值作为值
- ruby-on-rails - 无法使用 OCRA for Ruby 版本 2.7.2 创建 exe
- google-chrome - Chrome 浏览器控制台中的 ExpiredKeyMapError
- r - 如何使用 R 中的“rusquant”包从investing.com 中抓取信息
- wordpress - 事务性 smtp 电子邮件服务发件人
- java - bufferedwriter writer = new bufferedwriter(new filewriter(resource.getfile())); 不工作