mutate_at 使用 group_by 时的评估错误
mutate_at evaluation error when using group_by
mutate_at() 在与 group_by() 一起使用时以及在将列位置的数值向量作为第一个 (.vars) 参数进行插值时显示评估错误。
- 使用
R
3.4.2 和 dplyr
0.7.4 版本时出现问题
- 使用
R
3.3.2 和 dplyr
0.5.0 时工作正常
- 如果 .vars 是字符向量(列名)则工作正常
示例:
# Create example dataframe
Id <- c('10_1', '10_2', '11_1', '11_2', '11_3', '12_1')
Month <- c(2, 3, 4, 6, 7, 8)
RWA <- c(0, 0, 0, 1.579, NA, 0.379)
dftest = data.frame(Id, Month, RWA)
# Define column to fill NAs
nacol = c('RWA')
# Fill NAs with last period
dftest_2 <- dftest %>%
group_by(Id) %>%
mutate_at(which(names(dftest) %in% nacol),
funs(ifelse(is.na(.),0,.)))
Error in mutate_impl(.data, dots) :
Evaluation error: object 'NA' not found.
证明问题的更明智的例子:
# Create example dataframe
Id <- c('10_1', '10_2', '11_1', '11_3', '11_3', '12_1')
Month <- c(2, 3, 4, 6, 7, 8)
RWA <- c(0, 0, 0, 1.579, NA, 0.379)
dftest = data.frame(Id, Month, RWA)
# Define column to fill NAs
nacol = c('RWA')
# Fill NAs with last period
dftest_2 <- dftest %>%
group_by(Id) %>%
mutate_at(which(names(dftest) %in% nacol),
funs(na.locf(., na.rm=F)))
我们得到 NA 值的原因是我们从 which
得到的输出是 3,但我们按 'Id' 分组,所以在那之后只有 2 列。
dftest %>%
group_by(Id) %>%
mutate_at(which(names(dftest) %in% nacol)-1, funs(ifelse(is.na(.),0,.)))
# A tibble: 6 x 3
# Groups: Id [6]
# Id Month RWA
# <fctr> <dbl> <dbl>
#1 10_1 2 0.000
#2 10_2 3 0.000
#3 11_1 4 0.000
#4 11_2 6 1.579
#5 11_3 7 0.000
#6 12_1 8 0.379
此处不需要 group_by
部分,因为我们将其他列中的 NA 值更改为 0
dftest %>%
mutate_at(which(names(dftest) %in% nacol), funs(ifelse(is.na(.),0,.)))
这可能是一个错误,使用基于位置的方法有时会有风险。更好的选择是 names
dftest %>%
group_by(Id) %>%
mutate_at(intersect(names(.), nacol), funs(replace(., is.na(.), 0)))
注意:在所有这些情况下,都不需要 group_by
另一个选项是 replace_na
来自 tidyr
dftest %>%
tidyr::replace_na(as.list(setNames(0, nacol)))
mutate_at() 在与 group_by() 一起使用时以及在将列位置的数值向量作为第一个 (.vars) 参数进行插值时显示评估错误。
- 使用
R
3.4.2 和dplyr
0.7.4 版本时出现问题 - 使用
R
3.3.2 和dplyr
0.5.0 时工作正常 - 如果 .vars 是字符向量(列名)则工作正常
示例:
# Create example dataframe
Id <- c('10_1', '10_2', '11_1', '11_2', '11_3', '12_1')
Month <- c(2, 3, 4, 6, 7, 8)
RWA <- c(0, 0, 0, 1.579, NA, 0.379)
dftest = data.frame(Id, Month, RWA)
# Define column to fill NAs
nacol = c('RWA')
# Fill NAs with last period
dftest_2 <- dftest %>%
group_by(Id) %>%
mutate_at(which(names(dftest) %in% nacol),
funs(ifelse(is.na(.),0,.)))
Error in mutate_impl(.data, dots) :
Evaluation error: object 'NA' not found.
证明问题的更明智的例子:
# Create example dataframe
Id <- c('10_1', '10_2', '11_1', '11_3', '11_3', '12_1')
Month <- c(2, 3, 4, 6, 7, 8)
RWA <- c(0, 0, 0, 1.579, NA, 0.379)
dftest = data.frame(Id, Month, RWA)
# Define column to fill NAs
nacol = c('RWA')
# Fill NAs with last period
dftest_2 <- dftest %>%
group_by(Id) %>%
mutate_at(which(names(dftest) %in% nacol),
funs(na.locf(., na.rm=F)))
我们得到 NA 值的原因是我们从 which
得到的输出是 3,但我们按 'Id' 分组,所以在那之后只有 2 列。
dftest %>%
group_by(Id) %>%
mutate_at(which(names(dftest) %in% nacol)-1, funs(ifelse(is.na(.),0,.)))
# A tibble: 6 x 3
# Groups: Id [6]
# Id Month RWA
# <fctr> <dbl> <dbl>
#1 10_1 2 0.000
#2 10_2 3 0.000
#3 11_1 4 0.000
#4 11_2 6 1.579
#5 11_3 7 0.000
#6 12_1 8 0.379
此处不需要 group_by
部分,因为我们将其他列中的 NA 值更改为 0
dftest %>%
mutate_at(which(names(dftest) %in% nacol), funs(ifelse(is.na(.),0,.)))
这可能是一个错误,使用基于位置的方法有时会有风险。更好的选择是 names
dftest %>%
group_by(Id) %>%
mutate_at(intersect(names(.), nacol), funs(replace(., is.na(.), 0)))
注意:在所有这些情况下,都不需要 group_by
另一个选项是 replace_na
来自 tidyr
dftest %>%
tidyr::replace_na(as.list(setNames(0, nacol)))