Purrr安全地创建列表列表 [英] Purrr safely creating lists of lists
问题描述
我已经使用safely
捕获了我发出警告时在代码中发生的错误.但是,safely
的结果比我预期的要复杂得多.
I've used safely
to catch an error which occurs in my code when I'm purring. However, the result from safely
is much more complex than I anticipated.
首先,我们创建必要的功能和示例数据.
First we create the necessary functions and example data.
#base functions.
SI_tall <- function(topheight, age, si ){
paramasi <- 25
parambeta <- 7395.6
paramb2 <- -1.7829
refAge <- 100
d <- parambeta*(paramasi^paramb2)
r <- (((topheight-d)^2)+(4*parambeta*topheight*(age^paramb2)))^0.5
## height at reference age
h2 <- (topheight+d+r)/ (2+(4*parambeta*(refAge^paramb2)) / (topheight-d+r))
return(abs(h2 - si))
}
new.topheight <- function(my.si, my.age){
optim(par = list(topheight = 10), ## this topheight is just an initial value
method = 'L-BFGS-B', fn = SI_tall, si = my.si, age = my.age, lower= 0, upper=100)$par
}
#Creating the function which will display errors.
safe_new.topheight <- safely(new.topheight)
#Creating data
my.age <- seq(0,100, by=0.2)
my.si <- c(15)
si.crossing <- tidyr::crossing(my.si, my.age) %>% data.frame()
#Creating the column to be unnested.
si.crossing2<- si.crossing %>%
mutate(height=map2(my.si,my.age, safe_new.topheight))
但是,结果变得复杂起来,使我感到困惑-我什至不知道"height"列中的列表嵌套要走多远.这是我数据中前5行的内容:
However, the result becomes to complex for me to unnest - I don't even know how far down the nesting of lists in the ´height´ column goes. Here's a dput of the first 5 rows in my data:
structure(list(my.si = c(15, 15, 15, 15, 15), my.age = c(0, 0.2,
0.4, 0.6, 0.8), height = list(list(result = NULL, error = structure(list(
message = "L-BFGS-B needs finite values of 'fn'", call = optim(par = list(topheight = 10),
method = "L-BFGS-B", fn = SI_tall, si = my.si, age = my.age,
lower = 0, upper = 100)), class = c("simpleError", "error",
"condition"))), list(result = c(topheight = 0.000693170450744849),
error = NULL), list(result = c(topheight = 0.00205917508142004),
error = NULL), list(result = c(topheight = 0.00390099534708239),
error = NULL), list(result = c(topheight = 0.00639475141226834),
error = NULL))), row.names = c(NA, 5L), class = "data.frame")
有什么方法可以将其展平到列中吗?
Is there any way to flatten this down to the columns:
my.si,my.age,高度,错误.
my.si , my.age , topheight, error.
非常感谢!
推荐答案
区分safely
和possibly
可能会有所帮助. safely
很高兴查看发生了什么错误(以及发生在何处).最好与transpose
而不是tibble
一起使用. possibly
用于运行map
函数,即使它遇到错误也是如此.如果引发错误,它可以让您选择替代值otherwise
.
It might be helpful to distinguish between safely
and possibly
. safely
is great to see what error occurred (and where). It is best used with transpose
not inside of a tibble
. possibly
is used to run a map
function even if it throughs an error. It lets you choose an alternative value otherwise
if an error is thrown.
# use `transpose` on the height column to turn the list inside out
# which results in two lists `result` and `error`
# first lets have a look at the structure
si.crossing2$height %>%
transpose %>%
str
# then `pluck` the `error` list and remove all elements which are NULL
# with `compact` - here you can see the error that occurred
si.crossing2$height %>%
transpose %>%
pluck("error") %>%
compact
# `safely` is a great function to see what went wrong
# but its not very useful inside a tibbles list-column
# what you actually want to use is `possibly`
possib_new.topheight <- possibly(new.topheight, otherwise = NA)
# this will not tell you what went wrong, but instead yield `NA`
# when an error is thrown - important to use `otherwise = NA`,
# the default is NULL, which makes the output list shorter and
# won't fit to your tibble
si.crossing3 <- si.crossing %>%
mutate(height = map2_dbl(my.si,my.age, possib_new.topheight))
si.crossing3
#> # A tibble: 501 x 3
#> my.si my.age height
#> <dbl> <dbl> <dbl>
#> 1 15 0 NA
#> 2 15 0.2 0.000693
#> 3 15 0.4 0.00206
#> 4 15 0.6 0.00390
#> 5 15 0.8 0.00639
#> 6 15 1 0.00947
#> 7 15 1.2 0.0131
#> 8 15 1.4 0.0172
#> 9 15 1.6 0.0218
#> 10 15 1.8 0.0269
#> # … with 491 more rows
这篇关于Purrr安全地创建列表列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!