编辑我正在编辑这篇文章,以便在整个方法从一开始就错误的情况下提供更多的上下文。请参阅下面的“上下文”,试图更抽象地解释问题。
我已经看到了讨论在块中匹配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(subj,run,session))使用group_by操作并合并列表(我的计划是使用rlist :: list .merge)。
任何帮助都会受到大力赞赏!
答案 0 :(得分:2)
这是一个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
<强>加成强>
使用group_by
代替split
的2 100%tidyverse方法。一个do
,一个nest
和map
。 do
被软推荐为FYI,但在这里它提供了更紧凑和可读的语法:
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)