我正在编写一个函数,可以帮助我清理现场试验数据。我正在使用tidyeval NSE编写它来挑战自己,并确保该功能在我返回时易于使用。我想我差不多了,但是在运行测试框架时,我却失败了,并显示以下消息:
错误:由于类型不兼容,无法加入'plantid'x'year' (因数/整数)调用方:left_join_impl(x,y,by_x,by_y, aux_x,aux_y,na_matches,environment())
起初有人建议这可能是由于分组造成的,所以我在联接之前添加了ungroup(),但是问题仍然存在。
有什么方法可以解决此问题,而无需手动将年份更改为字符(?) 提前谢谢了。
功能
id_injured <- function(df, plantid, year, injuries, forbidden_values, monotonic_increase=FALSE,height){
#Converting variables in selectlist to character
df <- df %>% mutate_at(injuries,as.character)
#Parsing unquoted strings.
plantid <- enquo(plantid)
year <- enquo(year)
height <- enquo(height)
#Mark injured as 1.
Dataplantid <- df %>% mutate(is_injured = purrr::pmap_int(select(.,!!injuries), ~any(c(...) %in% !!forbidden_values)))
#Find time of first observed injury.
injuredlist <- Dataplantid %>% group_by(!!plantid) %>% filter(is_injured == 1) %>% summarise(firstinjury = min(!!year)) %>% ungroup()
#In plantid group, all years older than first injury are marked 1, else 0.
joinedinjured <- dplyr::left_join(x=Dataplantid, y=injuredlist, by = rlang::as_name(plantid))
joinedinjured <- joinedinjured %>% group_by(!!plantid) %>% mutate(afterfirstinjury = case_when(!!year >= firstinjury ~ 1,
!!year< firstinjury ~ 0))
returnvalues <- joinedinjured %>% select(!!plantid, !!year, firstinjury, afterfirstinjury) %>% ungroup()
##c() does not support rlang bangs (!!) but takes a string. Solution follows below approach
# from Lionel Henry, Stackoverflow: https://stackoverflow.com/a/58518138/11550980
returnvalues <- left_join(df, returnvalues, by=c(setNames(rlang::as_name(plantid),rlang::as_name(year))))
#Mark all prior to a break in monotonic growth as true.
if(monotonic_increase==TRUE){
returnvalues<- returnvalues %>% group_by(!!plantid) %>% arrange(!!plantid, !!year) %>%
tidyr::fill(!!height, .direction="downup") %>%
mutate(monotonic_growth = cumall(c(TRUE, diff(height) > 0))) %>% ungroup()
returnvalues
}
returnvalues
}
测试框架
plantid <- rep(c("A1","B2","C3","D4","E5"), times=c(3,3,3,3,3))
year <- rep(1:3, length.out=length(plantid))
set.seed(42)
PrimaryInjury <- sample(c(NA,NA,NA,"Rust","Insect","Snow break"), 15, replace=TRUE)
SecondaryInjury <- rep(NA, length.out=length(plantid))
OtherInjury <- rep(NA, length.out=length(plantid))
height <- c(1,2,3,1,2,3,3,2,1,1,2,3,1,3,2)
testframe <- data.frame(plantid,year,PrimaryInjury,SecondaryInjury, OtherInjury,height)
rm(OtherInjury)
rm(plantid)
rm(PrimaryInjury)
rm(SecondaryInjury)
rm(year)
rm(height)
运行功能-这会产生错误。
id_injured(df=testframe, plantid=plantid,year=year,injuries = c("PrimaryInjury","SecondaryInjury","OtherInjury"),forbidden_values = c("Rust","Insect","Snow break"),monotonic_increase = FALSE)