在编写一个旨在比较两个数据帧中的列的函数时,我希望弄清楚如何在 $ 之后引用指定为函数参数的变量。
考虑这个数据:
data1<-data.frame(ID=c(1,1,2,2,3,3),Amt=c(5,10,15,20,25,30),Term=c(2,3,2,3,2,3))
data2<-data.frame(Id=c(1,2,3),TERM=c(1,2,3))
Run Code Online (Sandbox Code Playgroud)
这个失败的功能:
two_df_function<-function(df,df2,id,id2,term,term2){
id<-rlang::ensym(id)
id2<-rlang::ensym(id2)
term<-rlang::ensym(term)
term2<-rlang::ensym(term2)
data_out<-df%>%
group_by(!!term)%>%
mutate(Early=ifelse(!!id %in% df2$!!id2[df2$!!term2 < !!term],1,0))
}
Run Code Online (Sandbox Code Playgroud)
我收到“错误:意外的‘!’ 在:”
为了得到我想要的结果,我手动插入了数据框和列名:
data_out<-data1%>%
group_by(Term)%>%
mutate(Early=ifelse(ID %in% data2$Id[data2$TERM < Term],1,0))
Run Code Online (Sandbox Code Playgroud)
产生:
因为我想要一个函数,所以我尝试通过简单地取出意外符号来解决。
以下将运行,但给出不正确的结果:
two_df_function<-function(df,df2,id,id2,term,term2){
id<-rlang::ensym(id)
id2<-rlang::ensym(id2)
term<-rlang::ensym(term)
term2<-rlang::ensym(term2)
data_out<-df%>%
group_by(!!term)%>%
mutate(Early=ifelse(!!id %in% df2$id2[df2$term2 < !!term],1,0))
return(data_out)
}
Run Code Online (Sandbox Code Playgroud)
使用后结果不正确:
有没有办法在 $ 之后砰的一声让我的功能成功?或者,是否有更好的方法来编写此函数以避免该问题?
我们可以在没有 $ 的情况下使用 bang bang dplyr,如下所示。顺便说一句,group_by如果您加入两个数据框,我认为在这种情况下不需要。
library(dplyr)
two_df <- function(df, df2, id, id2, term, term2){
df_out <- df %>%
left_join(df2, by = setNames(id2, id)) %>%
mutate(Early = as.integer(.data[[term]] > .data[[term2]])) %>%
select(-all_of(term2))
return(df_out)
}
two_df(data1, data2, id = "ID", id2 = "Id", term = "Term", term2 = "TERM")
# ID Amt Term Early
# 1 1 5 2 1
# 2 1 10 3 1
# 3 2 15 2 0
# 4 2 20 3 1
# 5 3 25 2 0
# 6 3 30 3 0
Run Code Online (Sandbox Code Playgroud)