1

my output a looks like:

str(a)
List of 8883695
 $ : chr [1:3] "20MICRONS" "A" "ACCRUALS"
 $ : chr [1:3] "20MICRONS" "A" "ACCRUALS"
 $ : chr [1:3] "20MICRONS" "A" "ACCRUALS"
 $ : chr [1:3] "20MICRONS" "A" "ACCRUALS"
 $ : chr [1:3] "20MICRONS" "A" "ACCRUALS"
 $ : chr [1:3] "20MICRONS" "A" "ACCRUALS"
 $ : chr [1:3] "20MICRONS" "A" "ACCRUALS"
 $ : chr [1:3] "20MICRONS" "A" "ACCRUALS"
 $ : chr [1:3] "20MICRONS" "A" "ACCRUALS"
 $ : chr [1:3] "20MICRONS" "A" "ACCRUALS"
 $ : chr [1:3] "20MICRONS" "A" "ACCRUALS"
 $ : chr [1:3] "20MICRONS" "A" "ACCRUALS"
 $ : chr [1:3] "20MICRONS" "A" "AE"
 $ : chr [1:3] "20MICRONS" "A" "AE"
 $ : chr [1:3] "20MICRONS" "A" "AE"

I want to convert this into a dataframe like:

ticker frequency field

20MICRONS A ACCRUALS
20MICRONS A ACCRUALS
20MICRONS A AE
20MICRONS A AE
20MICRONS A AE
20MICRONS A AE

I have tried this:

b <- as.data.frame(a)  
Error in sort.list(y) : 'x' must be atomic for 'sort.list'
Have you called 'sort' on a list?

But not working. Please help. I am new to R and stack overflow.

shivrajgondi
  • 21
  • 1
  • 4

4 Answers4

4

The list elements are not of equal length. So, we need to convert it to equal length by padding with NA

mx <- max(lengths(a))
d1 <- data.frame(lapply(a, `length<-`, mx))
akrun
  • 874,273
  • 37
  • 540
  • 662
  • @shivrajgondi This does correct it automatically by assigning elements that have less than the maximum length to pad with as many NAs to get all of them having the same length – akrun Apr 01 '17 at 16:50
  • Thanks Akrun, found certain vectors to be of length 4. – shivrajgondi Apr 01 '17 at 16:53
  • @shivrajgondi Your partial `str` output suggests the length as 3, may be it is 4 based on the full `str` – akrun Apr 01 '17 at 17:09
  • 1
    This is a very cool answer, it sparked for me a followup quesiton on replacement functions I posted here: https://stackoverflow.com/questions/69485776/why-dont-lambda-functions-handle-replacement-functions-in-their-intuitive-form – Bryan Shalloway Nov 22 '21 at 20:40
1

I found a function called do.call(rbind.data.frame, your_list) - seems like this is what you're looking for. Check the comments section of this question.

user_cm21
  • 23
  • 6
1
library(tidyverse)

a <- list(c("20M1", "A1", "ACC1"), 
          c("20M2", "A2", "ACC2"), 
          c("20M3"), 
          c("20M4", "A3"))

if_null_na <- function(x){
  if(is.null(x)) return(NA)
  x
}

a %>% 
  transpose() %>% 
  map(~map(.x, if_null_na)) %>% 
  map(unlist) %>% 
  as_tibble(.name_repair = "unique")
#> Warning: Element 3 must be length 3, not 1
#> Warning: Element 4 must be length 3, not 2
#> New names:
#> * `` -> ...1
#> * `` -> ...2
#> * `` -> ...3
#> # A tibble: 4 x 3
#>   ...1  ...2  ...3 
#>   <chr> <chr> <chr>
#> 1 20M1  A1    ACC1 
#> 2 20M2  A2    ACC2 
#> 3 20M3  <NA>  <NA> 
#> 4 20M4  A3    <NA>

Created on 2021-10-06 by the reprex package (v2.0.0)

Though this way is much slower than Akrun's approach.

Bryan Shalloway
  • 748
  • 7
  • 15
0

You could try Reduce(rbind, a), which is handy for that.

Kevin Zarca
  • 2,572
  • 1
  • 18
  • 18