R 中的 full_join 以 NA 作为通配符来匹配其他 data.frame 中的任何值

问题描述 投票:0回答:2

我正在寻找一种方法,使 dplyr'r full_join 将“by”列中的 NA 视为连接的通配符,即 NA 将匹配其他数据帧的相应列中的任何值并连接相应的行。

示例:我在 R 中有几个 data.frames,定义了某些产品特征,其中一些取决于更细粒度的特征,其他仅取决于高级产品类别:

x = data.frame(class = c("A", "B", "B", "C"), flags = c(NA, "individual", "group", NA), interest = c(0.04, 0.03, 0.02, 0.05));x
y = data.frame(class = c("A", "A", "B", "B", "C"), flags = c("individual", "group", "individual", "group", NA), costs = c(0.05, 0.025, 0.03, 0.02, 0.01));y
> x
  class      flags interest
1     A       <NA>     0.04
2     B individual     0.03
3     B      group     0.02
4     C       <NA>     0.05
> y
  class      flags costs
1     A individual 0.050
2     A      group 0.025
3     B individual 0.030
4     B      group 0.020
5     C       <NA> 0.010

现在我想将这两个连接起来创建一个产品特性表,但我希望“flags”列中的 NA 与另一个 data.frame 的 flags 列中的任何值匹配,从而产生以下联合 data.frame :

> expected
  class      flags interest costs
1     A individual     0.04 0.050
2     A      group     0.04 0.025
3     B individual     0.03 0.030
4     B      group     0.02 0.020
5     C       <NA>     0.05 0.010

不幸的是,full_join仅通过精确的字符串匹配进行匹配,因此flags列中的 不会匹配其他数据帧的flags列的任何值(“group”,“partner”,“individual”):

> actual = full_join(x,y, by=c("class","flags"));actual
  class      flags interest costs
1     A       <NA>     0.04    NA
2     B individual     0.03 0.030
3     B      group     0.02 0.020
4     C       <NA>     0.05 0.010
5     A individual       NA 0.050
6     A      group       NA 0.025

如何使 full_join 将 NA 视为匹配任何字符串(而不是仅匹配其他 NA)?

r dataframe dplyr
2个回答
2
投票

您只能在

class
列上加入,然后过滤:

library(dplyr)
x |>
  full_join(y, by = "class", relationship = "many-to-many") |>
  filter(flags.x == flags.y | is.na(flags.x) | is.na(flags.y)) |>
  mutate(flags = coalesce(flags.x, flags.y)) |>
  select(class, flags, interest, costs)
#   class      flags interest costs
# 1     A individual     0.04 0.050
# 2     A      group     0.04 0.025
# 3     B individual     0.03 0.030
# 4     B      group     0.02 0.020
# 5     C       <NA>     0.05 0.010

0
投票

我想知道您是否可以通过加入非

NA
列来尝试不同的方法。例如,每行
split
您的 data.frame,然后选择不是
NA
的列,并使用它们与第二个 data.frame 联接。对于
class
“A”,其中
NA
flags
,它将仅基于
class
进行连接;而对于
class
“B”,它将同时加入
class
flags

library(tidyverse)

x %>%
  split(seq(nrow(.))) %>%
  map_dfr(~.x %>%
             select_if(!is.na(.)) %>%
             inner_join(y, .))

输出

  class      flags costs interest
1     A individual 0.050     0.04
2     A      group 0.025     0.04
3     B individual 0.030     0.03
4     B      group 0.020     0.02
5     C       <NA> 0.010     0.05
© www.soinside.com 2019 - 2024. All rights reserved.