r-当无法插入组时,Mutate_at停止,tryCatch不起作用



我有如下数据:

library(data.table)
DT <- structure(list(country = c("Germany", "Germany", "Germany", "Germany", 
"Germany", "France", "France", "France", "France", "France", 
"UK", "UK", "UK", "UK", "UK"), year = c(2000, 2001, 2002, 2003, 
2004, 2000, 2001, 2002, 2003, 2004, 2000, 2001, 2002, 2003, 2004
), a = c(NA, NA, NA, NA, NA, NA, 1000, NA, 1600, NA, 1000, NA, 
1000, NA, NA), b = c(NA, NA, NA, NA, NA, NA, 1000, NA, 2200, 
NA, 1000, NA, 1000, NA, NA)), row.names = c(NA, -15L), class = c("data.table", 
"data.frame"))

我正在尝试插入一些值。

我试图重现这个错误(这当然是一个非常合乎逻辑的错误,因为没有德国的数据(:

Error: Problem with `mutate()` input `a`.
x need at least two non-NA values to interpolate
i Input `count` is `(structure(function (..., .x = ..1, .y = ..2, . = ..1) ...`.
i The error occurred in group 123: value = "group", country = "Arthur", State = "Nebraska".
Run `rlang::last_error()` to see where the error occurred.

带有以下代码:

library(tidyverse)
library(zoo)
st_example %>%
group_by(country) %>%
mutate_at(vars(a),~na.fill(.x,c(NA, "extend", NA))) %>% 
filter(!is.na(a))

我很遗憾没有得到我所期望的错误。

我的问题是,当mutate_at失败时,它不会继续下一组。我曾尝试围绕mutate_at(vars(a:b),~na.fill(.x,c(NA, "extend", NA))) %>%构建tryCatch,但没有成功。

如果遇到错误,如何告诉mutate_at继续?

您的错误是由zoo::na.fill而不是mutate_at()引发的。从控制台运行rlang::last_error()会使此问题浮出水面。

zoo::na.fill(c("hello",NA), c(NA, "extend", NA))
Error in approx(wix, unlist(object[wix]), xout = wrng) : 
need at least two non-NA values to interpolate

你可以用这样的东西破解它:

DT %>%
group_by(country) %>%
mutate_at(
vars(a),
~ tryCatch(
as.numeric(na.fill(.x,c(NA, "extend", NA))),
error = function(error) .x
)
) %>%
filter(!is.na(a))

顺便说一句,没有理由在示例代码中使用data.table——dplyr将强制data.table对象为data.frame

在不使用tryCatch((的情况下,以下内容应该可以工作:

DT %>%
split(.$country) %>%
purrr::map(~mutate(., a = as.numeric(na.fill(.x$a, c(NA, "extend", NA))))) %>%
bind_rows()

如果目标是按国家/地区对列a执行线性插值,则:

library(dplyr)
library(zoo)
DT %>% 
group_by(country) %>%
mutate(a = na.approx(a, na.rm = FALSE)) %>%
ungroup

或插入所有数字列:

DT %>% 
group_by(country) %>%
mutate(across(where(is.numeric), ~ na.approx(., na.rm = FALSE))) %>%
ungroup

相关内容

最新更新