【问题标题】:Mutate_at stops when it cannot interpolate a group, tryCatch does not workmutate_at 在无法插入组时停止,tryCatch 不起作用
【发布时间】:2021-03-27 06:29:39
【问题描述】:

我的数据如下:

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))) %&gt;% 周围构建一个tryCatch,但没有成功。

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

【问题讨论】:

    标签: r syntax interpolation na dplyr


    【解决方案1】:

    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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

        如果目标是按国家/地区对列 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
        

        【讨论】:

          猜你喜欢
          • 2017-08-05
          • 2014-10-08
          • 2010-10-16
          • 1970-01-01
          • 2017-02-14
          • 1970-01-01
          • 2012-08-05
          • 1970-01-01
          • 2018-03-26
          相关资源
          最近更新 更多