定制函数中的Dplyr不评估列。
我花了几个小时找出代码中的问题。我有一个具有几列的数据框(下面的示例),并在下面创建了传递数据框和列的函数。目标是进行滤波和变异以进行线性插值。但是,该函数不会读取参数列。
library(tidyverse)
library(imputeTS)
library(zoo)
dfm <- tbl_df(data.frame(country=rep('BGD', each=48), year=c(1970:2017),
STUNT=c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,
70.9, NA, NA, NA, 63.4, 73.6, 71.5, 69.2, 67.3,
65.8, 63.8, 59.7, 59.3, 59.9, 50.8, 53.2, 51.4, 47.8,
50.5, 45.9, 45.1, 43.2,NA, NA, NA, 41.4, 42,
38.7, 36.1, NA, NA, NA, NA)))
vari = "STUNT"
data_impute<- function(data, vari) {
data %>%
select(country, year, paste0(vari)) %>%
group_by(country) %>%
filter(seq_along(vari) >= min(which(!is.na(vari))) &
seq_along(vari) <= max(which(!is.na(vari)))) %>%
mutate(vari= na.interpolation(vari, option="linear")) %>%
select(country, year, paste0(vari)) %>%
ungroup()
}
当使用数据执行该函数时,它为STUNT列提供字符串“ STUNT”。我看到里面的dplyr操作不会评估从group_by到结尾的列。我读过许多其他类似的文章,但没有帮助。如果您能建议问题出在哪里,我将不胜感激。
答案 0 :(得分:1)
https://tidyeval.tidyverse.org/sec-why-how.html
dplyr
使用了一种“非标准评估”形式,这种形式在许多情况下非常方便,但是当您希望将其用于编程时,可以进行更多的工作。我认为以下代码可以正常工作,大概是另一个包中的na.interpolation
函数除外。我采用的方法是在变量上方“引用”变量,然后使用!!! (“ bang bang”)运算符在需要的地方取消报价。
data_impute<- function(data, vari) {
vari_quo <- enquo(vari)
data %>%
select(country, year, paste0(!!vari_quo)) %>%
group_by(country) %>%
filter(seq_along(!!vari_quo) >= min(which(!is.na(!!vari_quo))) &
seq_along(!!vari_quo) <= max(which(!is.na(!!vari_quo)))) %>%
# skipped next line b/c I don't have na.interpolation function
# mutate(!!vari_quo := na.interpolation(!!vari_quo, option="linear")) %>%
select(country, year, paste0(!!vari_quo)) %>%
ungroup()
}
data_impute(dfm, vari)
答案 1 :(得分:0)
您也可以使用!!rlang::ensym
。这接受参数为文字或字符串。
data_impute<-function(data, vari) {
data %>%
select(country, year, !!rlang::ensym(vari)) %>%
group_by(country) %>%
filter(seq_along(!!rlang::ensym(vari)) >= min(which(!is.na(!!rlang::ensym(vari)))) &
seq_along(!!rlang::ensym(vari)) <= max(which(!is.na(!!rlang::ensym(vari))))) %>%
mutate(vari := na_interpolation(!!rlang::ensym(vari), option="linear")) %>%
select(country, year, !!rlang::ensym(vari)) %>%
ungroup()
}
> head(data_impute(dfm, vari = STUNT))
# A tibble: 6 x 3
country year STUNT
<fct> <int> <dbl>
1 BGD 1985 70.9
2 BGD 1986 NA
3 BGD 1987 NA
4 BGD 1988 NA
5 BGD 1989 63.4
6 BGD 1990 73.6
> head(data_impute(dfm, vari = "STUNT"))
# A tibble: 6 x 3
country year STUNT
<fct> <int> <dbl>
1 BGD 1985 70.9
2 BGD 1986 NA
3 BGD 1987 NA
4 BGD 1988 NA
5 BGD 1989 63.4
6 BGD 1990 73.6