编辑我正在对这篇文章进行一些编辑,以提供更多背景信息,以防整个方法从一开始就是错误的。请参阅下面的“上下文”以尝试更抽象地解释问题。
我看过讨论 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
,一种带有 nest
和 map
。 do
已被软弃用(仅供引用),但这里它提供了更紧凑和可读的语法:
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/