r-在联接函数dplyr中通过参数编程使用



我想使用dplyr包的left_join函数的by参数,通过联接将具有与两个不同表的列名相对应的字符串名称的对象传递给。

以下是构建我想要加入的两个表的代码:

library(tidyverse)
v1<-letters[1:3] %>% factor
v2<-letters[5:7] %>% factor
yname<-"W"
names_vars<-c("sex","st")
all_comb<-expand.grid(v1,v2)
colnames(all_comb)<-names_vars
f1<-paste0(names_vars,collapse = "*") %>% {paste0("~ ",.)} %>% formula
mat <- model.matrix(f1, all_comb)
int_terms<- colnames(mat)[-1] %>% str_subset(":")
terms<-setdiff(colnames(mat)[-1],int_terms)
subindx<-terms %>% str_remove_all(paste0(names_vars,collapse = "|"))
nterms<-data.frame(var=names_vars,
nterms=all_comb %>% apply(2,function(x)length(unique(x))-1))
terms_df<-data.frame(var=rep(nterms$var,nterms$nterms),terms=subindx,type="s")
terms_df$xs<-paste0("x_",1:nrow(terms_df))
int_terms_df<-int_terms %>% str_split_fixed(":",2) %>% data.frame()
colnames(int_terms_df)<-names_vars
int_terms_df<-int_terms_df %>% 
apply(1:2,function(x)str_remove_all(x,paste0(names_vars,collapse = "|"))) %>% 
data.frame()

(很抱歉生成两个表的代码太长(。要连接的两个表是int_terms_dfterms_df

int_terms_df
sex st
1   b  f
2   c  f
3   b  g
4   c  g
terms_df[,c("terms","xs")]
terms  xs
1     b x_1
2     c x_2
3     f x_3
4     g x_4

我想加入的是:

left_join(int_terms_df,terms_df[,c("terms","xs")],by=c("sex"="terms")) %>% 
left_join(terms_df[,c("terms","xs")],by=c("st"="terms")) %>% 
mutate(xs=paste0(xs.x," ",xs.y),.keep ="unused")

制作此表:

sex st      xs
1   b  f x_1 x_3
2   c  f x_2 x_3
3   b  g x_1 x_4
4   c  g x_2 x_4

问题是,这段代码将是一个函数的主体,我需要对by参数进行操作,该参数将具有相应列的字符串名称的对象传递给left_join函数。

我已经审查了这些资源(r1,r2(,但提供的解决方案在我的情况下不起作用,例如r2:

xtemp<-"terms"
left_join(int_terms_df,terms_df[,c("terms","xs")],by=setNames(names_vars[1], xtemp))

生成下一条错误消息:

Error in `left_join()`:
! Join columns must be present in data.
✖ Problem with `terms`.
Run `rlang::last_error()` to see where the error occurred.

我确实注意到,r1和r2中的示例是同一数据帧上的连接,在这种情况下,要连接的表是不同的数据帧,我相信这可能是我在本例中实现这一点的失败原因。

我感谢你对此发表评论。

setNames中的命名应该颠倒,即无论变量的名称是什么,都应该与第一个数据集by变量匹配

library(dplyr)
left_join(int_terms_df,terms_df[,c("terms","xs")],
by=setNames(xtemp, names_vars[1]))

-输出

sex st  xs
1   b  f x_1
2   c  f x_2
3   b  g x_1
4   c  g x_2

对于right_join也是TRUE

> right_join(int_terms_df,terms_df[,c("terms","xs")],
by=setNames(xtemp, names_vars[1]))
sex   st  xs
1   b    f x_1
2   c    f x_2
3   b    g x_1
4   c    g x_2
5   f <NA> x_3
6   g <NA> x_4

最新更新