我发现在使用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
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
我正在使用Rstudio,以防与您的建议相关。
创建于 2019-10-15 由 reprex 软件包 (v0.3.0(
我们可以使用purrr
中的possibly
或safely
并指定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"
可以通过简单的检查找到
out$dataframes %in% 'error here'
#[1] FALSE FALSE TRUE
要查找位置,请用which
换行