NSE dplyr :: left_join因类型不兼容而失败

时间:2020-03-27 10:09:21

标签: r dplyr rlang tidyeval nse

我正在编写一个函数,可以帮助我清理现场试验数据。我正在使用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)

0 个答案:

没有答案