1

I am trying to graph the result of multiple runs of a function. The function returns an object that has lists of different lengths.

library(ldbounds)
reas1.lin = bounds(t = c(.5,.75,1),iuse = c(3,3),alpha = c(0.025,0.025))

the result looks like this:

$bounds.type
[1] 2

$spending.type
[1] "Power Family: alpha * t^phi"

$time
[1] 0.50 0.75 1.00

$time2
[1] 0.50 0.75 1.00

$alpha
[1] 0.025 0.025

$overall.alpha
[1] 0.05

$lower.bounds
[1] -2.241403 -2.288491 -2.229551

$upper.bounds
[1] 2.241403 2.288491 2.229551

$exit.pr
[1] 0.0250 0.0375 0.0500

$diff.pr
[1] 0.0250 0.0125 0.0125

attr(,"class")
[1] "bounds"

I would like to get a dataframe that looks like this:

time1 time2 lower.bound upper.bound exit.pr diffpr                        type 
0.50  0.50   -2.241403    2.241403  0.0250 0.0250 Power Family: alpha * t^phi       
0.75  0.75   -2.288491    2.288491  0.0375 0.0125 Power Family: alpha * t^phi       
1.00  1.00   -2.229551    2.229551  0.0500 0.0125 Power Family: alpha * t^phi       

This is how I extracted the data to the above dataframe, but it depends on the number of elements in each list, there must be a more elegant solution to this...

example1.lin <- data.frame(matrix(as.numeric(unlist(reas1.lin)[c(3:8,12:23)]), 
                    nrow=3,
                    byrow=F),type=reas1.lin$spending.type)
Esther
  • 441
  • 2
  • 15

2 Answers2

2

Here's one way:

nms <- c("time", "time2", "lower.bounds", "upper.bounds", "exit.pr", "diff.pr", "spending.type")
as.data.frame(reas1.lin[nms])
#   time time2 lower.bounds upper.bounds exit.pr diff.pr               spending.type
# 1 0.50  0.50    -2.241403     2.241403  0.0250  0.0250 Power Family: alpha * t^phi
# 2 0.75  0.75    -2.288491     2.288491  0.0375  0.0125 Power Family: alpha * t^phi
# 3 1.00  1.00    -2.229551     2.229551  0.0500  0.0125 Power Family: alpha * t^phi
Julius Vainora
  • 47,421
  • 9
  • 90
  • 102
1

Turns out someone was faster than I was (and uses less lines of code). If you are interested in a version that doesn't require manually inserting the names of your list, you can do this:

library(ldbounds)
library(tidyverse)
example1 = bounds(t = c(.5,.75,1),iuse = c(3,3),alpha = c(0.025,0.025))
example1 <- map(example1, `length<-`, max(lengths(example1)))
example1 %>% as_data_frame() %>% fill(everything())

First, I filled all vectors in the list with NAs to be the same lenght, then I combined them to a dataframe and replaced NAs with the value in the row above them if necessary. The sort of quirky and surprising but rather elegant way of just using the length-assignment as a function comes from an answer to this question.

Jannik Buhr
  • 1,788
  • 2
  • 11
  • 11
  • It adds unwanted columns and fills some other with values that shouldn't be there.. E.g., initially `alpha` has only two values but ultimately it has three (non `NA`). – Julius Vainora Mar 21 '18 at 18:01