r - Dplyr加入: NA match to any

标签 r dplyr tidyverse

编辑我正在对这篇文章进行一些编辑,以提供更多背景信息,以防整个方法从一开始就是错误的。请参阅下面的“上下文”以尝试更抽象地解释问题。

我看过讨论 tibbles 中 NA 匹配的线程,选项是将它们与其他 NA 匹配,或者不将它们与任何内容匹配: dplyr left_join matching NA

但是,我确实在寻找相反的行为。有没有办法让 NA(或该情况下的任何缺失值)在连接操作期间与任何其他值匹配?下面是一个例子:


library(tidyverse)
# Removed output for brevity

tbl1 <- tibble(subj = 1, run = 1, session=1)

tbl2 <- tibble(subj = c(1, NA, 2), run = c(NA, 1, 2), session=c(NA, NA, 1), outcomedata = c(NA, NA, NA) )

tbl2$outcomedata[2][[1]] <- list(temperature=30)
tbl2$outcomedata[1][[1]] <- list(height=155, weight=80)
tbl2$outcomedata[3][[1]] <- list(temperature=20)

tbl1
#> # A tibble: 1 x 3
#>    subj   run session
#>   <dbl> <dbl>   <dbl>
#> 1  1.00  1.00    1.00
tbl2
#> # A tibble: 3 x 4
#>    subj   run session outcomedata
#>   <dbl> <dbl>   <dbl> <list>     
#> 1  1.00 NA      NA    <list [2]> 
#> 2 NA     1.00   NA    <list [1]> 
#> 3  2.00  2.00    1.00 <list [1]>

left_join(tbl1, tbl2)
#> Joining, by = c("subj", "run", "session")
#> # A tibble: 1 x 4
#>    subj   run session outcomedata
#>   <dbl> <dbl>   <dbl> <list>     
#> 1  1.00  1.00    1.00 <NULL>

我期望的最终结果是我可以将 tbl2 的第一行和第二行与 tbl1 的单行匹配,因为这些行在所有非 NA 属性上匹配。第三行不应与任何内容匹配,因为它在非 NA 值上有所不同。因此,我试图让最终输出如下:

#> # A tibble: 2 x 4
#>    subj  run   session  outcomedata
#>   <dbl> <dbl>   <dbl>     <list>     
#> 1  1.00  1.00    1.00     <list [2]> 
#> 2  1.00  1.00    1.00     <list [1]> 

上下文

让我提供上下文,以防万一我离开这里并用连接吠叫错误的树,并且有一个更简单的替代方案。我有一堆嵌套的 json 文件(我在 R 中将其实例化为列表),其中包含我想要归因于数据中特定实例的各种信息。一个 json 可能包含与主题 1 的数据中的所有实例(即 tbl2 的第一行)相关的信息,而另一个 json 可能包含与运行 1 的数据中的所有实例(即 tbl2 的第二行)相关的信息。

我希望能够将数据中每个参数组的所有相关信息(其中一个位于 tbl1 中,但计划是将它们全部包含在内)合并到单独的列表中。我的计划是尝试让所有内容与所有相关内容匹配,然后对所有参数使用 group_by 操作(即 group_by(subj, run, session))并合并列表(我的计划是使用 rlist::list .合并)。

任何帮助将不胜感激!

最佳答案

这是一个 tidyverse 解决方案:

tbl2 %>%
  split(seq(nrow(.))) %>%               # split into one row data frames
  map_dfr(~modify_if(.,is.na,~NULL) %>% # remove na columns
        inner_join(tbl1,.))             # inner join to table1

# # A tibble: 2 x 4
#    subj   run session outcomedata
#       <dbl> <dbl>   <dbl> <list>     
# 1     1     1       1 <list [2]> 
# 2     1     1       1 <list [1]>

我使用 inner_join(tbl1,.) 而不是 inner_join(tbl1) 来保留列顺序。

以及基本的 R 翻译:

df_list <- split(tbl2,seq(nrow(tbl2)))
df_list <- lapply(df_list,function(dfi){
  merge(tbl1, dfi[!sapply(dfi,is.na)])
})
do.call(rbind,df_list)
#   subj run session outcomedata
# 1    1   1       1     155, 80
# 2    1   1       1          30

奖金

2 100% tidyverse 方法使用 group_by 而不是 split。一种带有 do,一种带有 nestmapdo 已被软弃用(仅供引用),但这里它提供了更紧凑和可读的语法:

tbl2 %>%
  group_by(n=seq(n())) %>%
  do(modify_if(.,is.na,~NULL) %>% # remove na columns
            inner_join(tbl1,.)) %>%
  ungroup %>%
  select(-n)

tbl2 %>%
  rowid_to_column("n") %>%
  group_by(n) %>%
  nest(.key="dfi") %>%
  mutate_at("dfi",~map(.,
                       ~ modify_if(.,is.na,~NULL) %>% # remove na columns
                         inner_join(tbl1,.))) %>%
  unnest %>%
  select(-n)

关于r - Dplyr加入: NA match to any,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50483890/

相关文章:

r - 使用 rowwise() 计算数据帧每一行中 NA 的数量的问题

RStudio 无法读取 GBP 英镑符号

r - 在 y 轴上方添加空间而不用 expand()

r - dplyr 中的向量化列运算

r - R 中缺失日期/值的“插值”?

r - 使用R中的unite函数并删除重复值

r - 如何为 `id` 创建 `pivot_longer()`

r - R 中跨列的条件变异

r - 在谷歌静态 map 上离线绘制 map 坐标

r - 如何使用 tidyverse : tibble, purrr, dplyr 在列表列上设置名称