return 映射的 object if purrr:possibly() 内的表达式失败
return the mapped object if expression inside of purrr:possibly() fails
我有一个数据框,其中一列包含更多数据框。其中一个数据框缺少一列。我想从其他两个数据框中删除该列(如果存在)。
这是一个例子:
library(tidyverse)
mtcars %>%
group_by(cyl) %>%
nest -> tmp
tmp[3,'data'][[1]][[1]] <- dplyr::select(tmp[3,'data'][[1]][[1]], -mpg)
print(tmp)
# A tibble: 3 x 2
cyl data
<dbl> <list>
1 6. <tibble [7 × 10]>
2 4. <tibble [11 × 10]>
3 8. <tibble [14 × 9]>
所以在这里,data
列包含三个小标题,最后一个不包含 mpg
列。我可以将 dplyr::select 映射到数据列上,并通过 returning NA
捕获错误,如下所示:
tmp %>% mutate(data2 = map(data, possibly(~dplyr::select(.,-mpg), otherwise = NA)))
# A tibble: 3 x 3
cyl data data2
<dbl> <list> <list>
1 6. <tibble [7 × 10]> <tibble [7 × 9]>
2 4. <tibble [11 × 10]> <tibble [11 × 9]>
3 8. <tibble [14 × 9]> <lgl [1]>
但我真正想做的是 return 输入数据。类似于:
tmp %>% mutate(data2 = map(data, possibly(~dplyr::select(.,-mpg), otherwise = function(x){x})))
# A tibble: 3 x 3
cyl data data2
<dbl> <list> <list>
1 6. <tibble [7 × 10]> <tibble [7 × 9]>
2 4. <tibble [11 × 10]> <tibble [11 × 9]>
3 8. <tibble [14 × 9]> <fn>
当然这只是 returns function(x){x}
作为 data2
的最后一行。
有什么妙招吗?或者在这种情况下我只需要使用 tryCatch
或更明确地处理错误?
possibly
中的otherwise
参数是一个常量,所以不会随着包装函数的输入而改变;你可能做的是将 possibly
包装在另一个可以从 data
访问元素的函数中,将元素设置为 otherwise
:
my_select <- function(x) {
f = possibly(function() select(x, -mpg), otherwise = x)
f()
}
tmp %>% mutate(data2 = map(data, my_select))
# A tibble: 3 x 3
# cyl data data2
# <dbl> <list> <list>
#1 6.00 <tibble [7 x 10]> <tibble [7 x 9]>
#2 4.00 <tibble [11 x 10]> <tibble [11 x 9]>
#3 8.00 <tibble [14 x 9]> <tibble [14 x 9]>
或采用公式形式:
tmp %>%
mutate(data2 = map(data, ~ (invoke(possibly(function() select(.,-mpg), otherwise = .)))))
# A tibble: 3 x 3
# cyl data data2
# <dbl> <list> <list>
#1 6 <tibble [7 × 10]> <tibble [7 × 9]>
#2 4 <tibble [11 × 10]> <tibble [11 × 9]>
#3 8 <tibble [14 × 9]> <tibble [14 × 9]>
我有一个数据框,其中一列包含更多数据框。其中一个数据框缺少一列。我想从其他两个数据框中删除该列(如果存在)。
这是一个例子:
library(tidyverse)
mtcars %>%
group_by(cyl) %>%
nest -> tmp
tmp[3,'data'][[1]][[1]] <- dplyr::select(tmp[3,'data'][[1]][[1]], -mpg)
print(tmp)
# A tibble: 3 x 2 cyl data <dbl> <list> 1 6. <tibble [7 × 10]> 2 4. <tibble [11 × 10]> 3 8. <tibble [14 × 9]>
所以在这里,data
列包含三个小标题,最后一个不包含 mpg
列。我可以将 dplyr::select 映射到数据列上,并通过 returning NA
捕获错误,如下所示:
tmp %>% mutate(data2 = map(data, possibly(~dplyr::select(.,-mpg), otherwise = NA)))
# A tibble: 3 x 3 cyl data data2 <dbl> <list> <list> 1 6. <tibble [7 × 10]> <tibble [7 × 9]> 2 4. <tibble [11 × 10]> <tibble [11 × 9]> 3 8. <tibble [14 × 9]> <lgl [1]>
但我真正想做的是 return 输入数据。类似于:
tmp %>% mutate(data2 = map(data, possibly(~dplyr::select(.,-mpg), otherwise = function(x){x})))
# A tibble: 3 x 3 cyl data data2 <dbl> <list> <list> 1 6. <tibble [7 × 10]> <tibble [7 × 9]> 2 4. <tibble [11 × 10]> <tibble [11 × 9]> 3 8. <tibble [14 × 9]> <fn>
当然这只是 returns function(x){x}
作为 data2
的最后一行。
有什么妙招吗?或者在这种情况下我只需要使用 tryCatch
或更明确地处理错误?
possibly
中的otherwise
参数是一个常量,所以不会随着包装函数的输入而改变;你可能做的是将 possibly
包装在另一个可以从 data
访问元素的函数中,将元素设置为 otherwise
:
my_select <- function(x) {
f = possibly(function() select(x, -mpg), otherwise = x)
f()
}
tmp %>% mutate(data2 = map(data, my_select))
# A tibble: 3 x 3
# cyl data data2
# <dbl> <list> <list>
#1 6.00 <tibble [7 x 10]> <tibble [7 x 9]>
#2 4.00 <tibble [11 x 10]> <tibble [11 x 9]>
#3 8.00 <tibble [14 x 9]> <tibble [14 x 9]>
或采用公式形式:
tmp %>%
mutate(data2 = map(data, ~ (invoke(possibly(function() select(.,-mpg), otherwise = .)))))
# A tibble: 3 x 3
# cyl data data2
# <dbl> <list> <list>
#1 6 <tibble [7 × 10]> <tibble [7 × 9]>
#2 4 <tibble [11 × 10]> <tibble [11 × 9]>
#3 8 <tibble [14 × 9]> <tibble [14 × 9]>