Сбой dplyr :: left_join в NSE из-за несовместимых типов - PullRequest
0 голосов
/ 27 марта 2020

Я пишу функцию, которая помогает мне очистить данные полевых испытаний. Я пишу это с использованием 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)
...