使用purrr时如何定位错误和调试

Ste*_*ted 8 debugging r purrr

我发现在使用purrr和某些map()变体时很难调试我的代码。特别是我在定位代码失败的位置时遇到问题,因为错误消息没有告诉我哪一行(数据帧)引发了错误。

使用时定位错误的好方法是什么purrr

考虑以下示例:

library(tidyverse)

# Prepare some data
set.seed(1)
a <- tibble(
  x = rnorm(2),
  y = rnorm(2))

b <- tibble(
  x = rnorm(2),
  y = rnorm(2))

c <- tibble(
  x = rnorm(2),
  y = letters[1:2])

df <- tibble(
  dataframes = list(a,b,c))

df
#> # A tibble: 3 x 1
#>   dataframes      
#>   <list>          
#> 1 <tibble [2 x 2]>
#> 2 <tibble [2 x 2]>
#> 3 <tibble [2 x 2]>

# A simple function 
add_cols <- function(.data){
  .data %>% 
    mutate(
      z = x + y)
}

# Running the function with map() will return an error
df %>% 
  mutate(
    dataframes = map(.x = dataframes, ~add_cols(.x)))
#> Error in x + y: non-numeric argument to binary operator
Run Code Online (Sandbox Code Playgroud)

map()返回错误,因为您无法添加数字和字母。错误消息告诉我们出了什么问题,但没有告诉我们哪里出了问题。在这个例子中,很明显错误来自 中的第三行df,但想象这个函数要复杂得多,我们将它应用于 1000 行。那么如何定位错误呢?

到目前为止,我的方法是使用循环的这种怪物的某个版本。我认为这种方法的缺点是很明显的。请帮我找到一个更好的方法来做到这一点。

for(i in 1:nrow(df)){
  print(paste("Testing row number", i))

  df %>% 
    filter(row_number() == i) %>% 
    unnest(cols = c(dataframes)) %>% 
    add_cols()
}
#> [1] "Testing row number 1"
#> [1] "Testing row number 2"
#> [1] "Testing row number 3"
#> Error in x + y: non-numeric argument to binary operator
Run Code Online (Sandbox Code Playgroud)

如果与您的建议相关,我正在使用 Rstudio。

reprex 包(v0.3.0)于 2019 年 10 月 15 日创建

akr*_*run 8

我们可以使用possiblysafelyfrompurrr并指定otherwise.

library(dplyr)
library(purrr)
out <- df %>%
         mutate(dataframes = map(dataframes, ~ 
                possibly(add_cols, otherwise = 'error here')(.x)))

out$dataframes
#[[1]]
# A tibble: 2 x 3
#       x      y     z
#   <dbl>  <dbl> <dbl>
#1 -0.626 -0.836 -1.46
#2  0.184  1.60   1.78

#[[2]]
# A tibble: 2 x 3
#       x     y       z
#   <dbl> <dbl>   <dbl>
#1  0.330 0.487  0.817 
#2 -0.820 0.738 -0.0821

#[[3]]
#[1] "error here"
Run Code Online (Sandbox Code Playgroud)

可以通过简单的检查找到

out$dataframes %in%  'error here'
#[1] FALSE FALSE  TRUE
Run Code Online (Sandbox Code Playgroud)

要找到位置,请用 which