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