作为一个更大的函数的一部分,它只保留在每个个体(plantid)受伤之前发生的植物生长的时间序列中的值,我正在编写两个块,按照顺序,它将包含一个函数
参数中给出的所有变量都是字符向量(如第二个函数中的那样,%in%不识别命名的因素),如果没有,则转换为字符,同时从上述给定变量(包括参数b.中的一个字符串)提供一个和标记行。
我确信引号/准引号或爆炸(!!)/大爆炸(!!!)运算符(这是我第一次用引号编写函数)出了问题。我一直被给予“!!!不可能在顶层使用”的警告,或者类似的警告,我不知道如何解决。我还需要帮助找到一种很好的方法来尝试转换不是字符的变量。
这就是我到目前为止所得到的
论证描述
df:data.frameplantid:唯一标识符,用于每一个plantyear:年份的observationinjuries:列表(在我的例子中)3列,这些列可以包含一个伤害代码,例如c("PrimaryInjury", "SecondaryInjury", "OtherInjury")forbidden_values:所关心的伤害代码,例如c("Rust", "Insect", "Snow break")函数
id_injured <- function(df, plantid, year, injuries, forbidden_values){
#parsing unquoted strings.
plantid <- enquo(plantid)
year <- enquo(year)
forbidden_values <- enquos(forbidden_values)
injuries <- syms(injuries)
#if all variables in injuries are not characters, stop and warn (attempt to convert to character those variables which are not character)
if(!all(purrr::pmap_int(select(df, !!!injuries), ~is.character(...))))){
stop("All injury variables are not characters. Convert factors in injuries to character variables")} else {
(1) #Control to give output while testing function, replace with conversion and warning?
}
#Identify rows with matching injury codes with 1, else 0.
Dataplantid <- df %>% mutate(is_injured = purrr::pmap_int(select(df, !!!injuries), any(c(...) %in% !!!forbidden values)))
#End of function
}预定用途
我删除了函数的第(1)部分,这样它只会标记1或0。
Dataplantid <- id_injured(df=df, plantid=plantid, year=year, injuries=c("PrimaryInjury","SecondaryInjury","OtherInjury"),forbidden_values=c("Rust","Insect","Snow break")结果
错误:无法在顶层使用
!!!。
> last_trace()
<error/rlang_error>
Can't use `!!!` at top level.
Backtrace:
█
1. └─global::so_injured(...)
2. └─`%>%`(...)
3. ├─base::withVisible(eval(quote(`_fseq`(`_lhs`)), env, env))
4. └─base::eval(quote(`_fseq`(`_lhs`)), env, env)
5. └─base::eval(quote(`_fseq`(`_lhs`)), env, env)
6. └─`_fseq`(`_lhs`)
7. └─magrittr::freduce(value, `_function_list`)
8. ├─base::withVisible(function_list[[k]](value))
9. └─function_list[[k]](value)
10. ├─dplyr::mutate(...)
11. └─dplyr:::mutate.data.frame(...)
12. ├─base::as.data.frame(mutate(tbl_df(.data), ...))
13. ├─dplyr::mutate(tbl_df(.data), ...)
14. └─dplyr:::mutate.tbl_df(tbl_df(.data), ...)
15. └─rlang::enquos(..., .named = TRUE)
16. └─rlang:::endots(...)
17. └─rlang:::map(...)
18. └─base::lapply(.x, .f, ...)
19. └─rlang:::FUN(X[[i]], ...)
20. └─rlang::splice(...)关联数据
plantid <- rep(c(1,2,3,4,5), 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)) #Filled with NA for example
OtherInjury <- rep(NA, length.out=length(plantid)) #Filled NA for example
df <- data.frame(plantid,year,PrimaryInjury,SecondaryInjury,OtherInjury)
#Right now, PrimaryInjury is a factor, SecondaryInjury and OtherInjury are logical.预期产出
Dataplantid <- df
Dataplantid$is_injured <- c(0,1,0,0,0,1,0,0,0,1,0,1,1,1,0)发布于 2020-03-24 13:21:14
有几个问题,从至少到最有问题的问题:
map_lgl而不是map_int。特别是使用map_lgl而不是pmap_int,除非您实际上打算并行地映射多个参数,这不是这种情况。H 110不要将函数结果分配给函数中的变量。它并不真正有害,但它是不必要的,misleading.
Do没有引用,然后插值forbidden_values值。您希望在这里使用字符向量,而不是R名。在计算is_injured.The逻辑以识别受损值的purrr调用中,--您丢失了一个~ --并不完全是这样工作的;在这里可能有一种使用pmap_lgl的方法,但我认为将数据重新格式化为长格式(尽管可能更详细)更简单,并使用它。加在一起,我们得到:
id_injured <- function(df, plantid, year, injuries, forbidden_values) {
plantid <- enquo(plantid)
year <- enquo(year)
injuries <- syms(injuries)
df_injuries <- select(df, !!! injuries)
if (! all(purrr::map_lgl(df_injuries, is.character))) {
stop("All injury variables are not characters. Convert factors in injuries to character variables")
}
is_injured <- df_injuries %>%
mutate(.RowID = row_number()) %>%
tidyr::gather(Key, Value, -.RowID) %>%
group_by(.RowID) %>%
summarize(is_injured = any(Value %in% forbidden_values)) %>%
pull(is_injured)
df %>% mutate(is_injured = is_injured)
}https://stackoverflow.com/questions/60828159
复制相似问题