Here's one way:

R> as.data.frame(as.matrix(h1))
                            V1
USA             10, 13, 17, 11
RUSSIA                    NULL
BRAZIL                    NULL
CHINA        11, 11, 10, 8, 12
TAIWAN 12, 9, 9, 11, 9, 12, 14
CHILE                     NULL

R> as.data.frame(as.matrix(h1))['TAIWAN', ]
$TAIWAN
[1] 12  9  9 11  9 12 14
Answer from GSee on Stack Overflow
🌐
Robwiederstein
robwiederstein.org › 2021 › 04 › 04 › convert-list-of-unequal-length-to-dataframe
Convert List of Unequal Length to Dataframe - Rob Wiederstein
April 4, 2021 - Lists as a data type can be confusing but also useful. They can hold data of different types and lengths, making them very versatile. Lists can be named or nested and have the same or different lengths. This post deals with converting a list to a dataframe when it has unequal lengths.
🌐
R-bloggers
r-bloggers.com › r bloggers › an easy to convert list to long table
An easy to convert list to long table | R-bloggers
December 12, 2021 - Martin Stingl posted a relevant solution for using map_dfr: https://rstats-tips.net/2021/02/07/converting-lists-of-lists-of-lists-to-data-frames-or-tibbles/, but didn’t solve the row name problem. ... genesets_df = data.frame(pathwayID=rep(names(genesets_list), lengths(genesets_list)), geneSymbol=genesets_list %>% map_dfr(as_tibble))
Find elsewhere
Top answer
1 of 2
1

Approach one:

First, we get the matrices to data.frames, then we add the rownames as a separate column called a, and gather them all. By unnesting we get one big data.frame. Adding in the NA values is easy with complete

library(tidyverse) # using dplyr, tidyr and purrr

df %>% 
  mutate(Value = map(Value, as.data.frame),
         Value = map(Value, rownames_to_column, 'a'),
         Value = map(Value, ~gather(., b, value, -a))) %>% 
  unnest(Value) %>% 
  complete(Step, a, b)

Approach two:

Manually define the data.frame, then do the same:

df %>% 
  mutate(Value = map(Value, 
                     ~data_frame(val = c(.), 
                                 a = rep(rownames(.), each = ncol(.)),
                                 b = rep(colnames(.), nrow(.))))) %>% 
  unnest(Value) %>% 
  complete(Step, a, b))

Result:

Both give:

# A tibble: 30 × 4
    Step     a     b value
   <int> <chr> <chr> <dbl>
1      1     4  0.01    NA
2      1     4 0.021    NA
3      1     4 0.044    NA
4      1     4 0.094 0.932
5      1     4   0.2 0.232
6      1     5  0.01    NA
7      1     5 0.021    NA
8      1     5 0.044    NA
9      1     5 0.094 0.875
10     1     5   0.2 0.261
# ... with 20 more rows
2 of 2
1

Not really a dplyr solution, but you could do:

## Get the maximum length in l$Value and the index where it is observed
m = max(lengths(l$Value))
[1] 10
j = which.max(lengths(l$Value))
[1] 2

Then construct a dataframe for each element of l$Value, rbind them together and add the Step column:

l2 = lapply(l$Value,function(x) data.frame(a=rep(row.names(x),length.out=m),
Value=x[1:m],b=rep(colnames(l$Value[[j]]),length.out=m)))
df = do.call(rbind,l2)
df$Step = rep(l$Step,each=m)

This returns:

   a Value     b Step
1  4 0.232   0.2    1
2  5 0.261 0.094    1
3  4 0.932 0.044    1
4  5 0.875 0.021    1
5  4    NA  0.01    1
6  5    NA   0.2    1
7  4    NA 0.094    1
8  5    NA 0.044    1
9  4    NA 0.021    1
10 5    NA  0.01    1
11 4 0.197   0.2    2
12 5 0.197 0.094    2
13 4 0.640 0.044    2
14 5 0.643 0.021    2
15 4 0.958  0.01    2
16 5 1.032   0.2    2
17 4 0.943 0.094    2
18 5 1.119 0.044    2
19 4 0.943 0.021    2
20 5 1.119  0.01    2
21 4 0.268   0.2    3
22 5 0.262 0.094    3
23 4    NA 0.044    3
24 5    NA 0.021    3
25 4    NA  0.01    3
26 5    NA   0.2    3
27 4    NA 0.094    3
28 5    NA 0.044    3
29 4    NA 0.021    3
30 5    NA  0.01    3
🌐
GeeksforGeeks
geeksforgeeks.org › function-to-transform-lists-of-different-lengths-into-data-frame-utilizing-recycling-in-r
Function to transform lists of different lengths into data frame utilizing recycling in R - GeeksforGeeks
July 22, 2024 - as.list() function in R Programming Language is used to convert an object to a list. These objects can be Vectors, Matrices, Factors, and dataframes.
Top answer
1 of 2
3

Here is a modified version with length<- assignment

setNames(do.call(cbind.data.frame, lapply(lapply(SampleData, unlist), 
        `length<-`, max(lengths(SampleData)))), paste0("V", 1:3))
#  V1 V2 V3
#1  1  1  3
#2  2  2  4
#3  3 NA  6
#4 NA NA  7
2 of 2
2

My first instinct looking at your data is that, by using a data.frame, you are implicitly stating that items across a row are paired. That is, in your example, the "3" of $V1 and "6" of $V3 are meant to be associated with each other. (If you look at mtcars, each column of the first row is associated directly and solely with the "Mazda RX4".) If this is not true, then warping them into a data.frame like this is mis-representing your data and like to encourage incorrect analysis/assumptions.

Assuming that they are in fact "paired", my next instinct is to try something like do.call(cbind, SampleData), but that lends to recycled data, not what you want. So, the trick to deter recycling is to force them to be all the same length.

maxlen <- max(lengths(SampleData))
SampleData2 <- lapply(SampleData, function(lst) c(lst, rep(NA, maxlen - length(lst))))

We can rename first:

names(SampleData2) <- paste("V", seq_along(SampleData2), sep = "")

Since the data appears homogenous (and should be, if you intend to put each element as a column of a data.frame), it is useful to un-list it:

SampleData3 <- lapply(SampleData2, unlist)

Then it's as straight-forward as:

as.data.frame(SampleData3)
#   V1 V2 V3
# 1  1  1  3
# 2  2  2  4
# 3  3 NA  6
# 4 NA NA  7
🌐
Rstats-tips
rstats-tips.net › 2021 › 02 › 07 › converting-lists-of-lists-of-lists-to-data-frames-or-tibbles
Converting Lists of Lists of Lists to Data.Frames (or Tibbles) - rstats-tips.net
February 7, 2021 - So use a version of all of these fantastic map-function from the purrr-package: (Read here for other fantastic stuff of purrr.) Look’s nice. But the original list consists of 5 rows. The result above is twice as long. So what happend? as_tibble generates for each entry of the list of the inner lists a row.
Top answer
1 of 1
4

Would this work for you ?

library(jsonlite)
library(tidyverse)
data = fromJSON("http://search.worldbank.org/api/v2/wds?format=json&fl=abstracts,admreg,alt_title,authr,available_in,bdmdt,chronical_docm_id,closedt,colti,count,credit_no,disclosure_date,disclosure_type,disclosure_type_date,disclstat,display_title,docdt,docm_id,docna,docty,dois,entityid,envcat,geo_reg,geo_reg,geo_reg_and_mdk,guid,historic_topic,id,isbn,ispublicdocs,issn,keywd,lang,listing_relative_url,lndinstr,loan_no,majdocty,majtheme,ml_abstract,ml_display_title,new_url,owner,pdfurl,prdln,projectid,projn,publishtoextweb_dt,repnb,repnme,seccl,sectr,src_cit,subsc,subtopic,teratopic,theme,topic,topicv3,totvolnb,trustfund,txturl,unregnbr,url_friendly_title,versiontyp,versiontyp_key,virt_coll,vol_title,volnb&str_docdt=1986-01-01&end_docdt=2000-12-31&rows=500&os=1&srt=docdt&order=desc")

df <- 
  data$documents %>%
  head(-1)       %>% # remove facet element
  transpose      %>% # transpose so each subelement is now a main element
  as_tibble      %>% # convert to table
  purrr::modify(~replace(.x,lengths(.x)==0,list(NA))) %>% # replace empty elements by list(NA) so they have length 1 too
  modify_if(~all(lengths(.x)==1),unlist) # unlist lists that contain only items of length 1

Only one list column remains:

names(df)[map_chr(df,class) == "list"]
# [1] "keywd"

As it contains items of length 1 or 2:

table(lengths(df$keywd))
#   1   2 
# 224 276

Here's what the output looks like:

glimpse(df)

# Observations: 500
# Variables: 38
# $ url                  <chr> "http://documents.worldbank.org/curated/en/903231468764970044/Attacking-rural-poverty-strategy-and-public-actions", "...
# $ available_in         <chr> "English", "English", "English", "English", "English", "English,French,Spanish,Portuguese", "Portuguese,Chinese,Engli...
# $ url_friendly_title   <chr> "http://documents.worldbank.org/curated/en/903231468764970044/Attacking-rural-poverty-strategy-and-public-actions", "...
# $ new_url              <chr> "2000/12/1000476/Attacking-rural-poverty-strategy-and-public-actions", "2000/12/1000501/State-policies-and-womens-aut...
# $ guid                 <chr> "903231468764970044", "429001468753367328", "985531468746683502", "890081468757236671", "922151468776107524", "324581...
# $ disclosure_date      <chr> "2010-07-01T00:00:00Z", "2010-07-01T00:00:00Z", "2010-07-01T00:00:00Z", "2010-07-01T00:00:00Z", "2010-07-01T00:00:00Z...
# $ disclosure_type      <chr> "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA...
# $ disclosure_type_date <chr> "2010-07-01T00:00:00Z", "2010-07-01T00:00:00Z", "2010-07-01T00:00:00Z", "2010-07-01T00:00:00Z", "2010-07-01T00:00:00Z...
# $ publishtoextweb_dt   <chr> "2010-07-01T00:00:00Z", "2010-07-01T00:00:00Z", "2010-07-01T00:00:00Z", "2010-07-01T00:00:00Z", "2010-07-01T00:00:00Z...
# $ docm_id              <chr> "090224b0828c737a", "090224b0828ac316", "090224b0828bd3f7", "090224b0828ac343", "090224b0828cf43d", "090224b0828cf42b...
# $ chronical_docm_id    <chr> "090224b0828c737a", "090224b0828ac316", "090224b0828bd3f7", "090224b0828ac343", "090224b0828cf43d", "090224b0828cf42b...
# $ txturl               <chr> "http://documents.worldbank.org/curated/en/903231468764970044/text/multi-page.txt", "http://documents.worldbank.org/c...
# $ pdfurl               <chr> "http://documents.worldbank.org/curated/en/903231468764970044/pdf/multi-page.pdf", "http://documents.worldbank.org/cu...
# $ docdt                <chr> "2000-12-31T00:00:00Z", "2000-12-31T00:00:00Z", "2000-12-31T00:00:00Z", "2000-12-31T00:00:00Z", "2000-12-31T00:00:00Z...
# $ totvolnb             <chr> "1", "1", "1", "1", "5", "1", "1", "14", "1", "1", "1", "1", "14", "14", "14", "14", "14", "14", "14", "14", "14", "1...
# $ versiontyp           <chr> "Final", "Final", "Final", "Final", "Final", "Final", "Final", "Final", "Final", "Final", "Final", "Final", "Final", ...
# $ versiontyp_key       <chr> "1309935", "1309935", "1309935", "1309935", "1309935", "1309935", "1309935", "1309935", "1309935", "1309935", "130993...
# $ volnb                <chr> "1", "1", "1", "1", "4", "1", "1", "8", "1", "1", "1", "1", "13", "4", "9", "12", "3", "2", "7", "10", "1", "6", "11"...
# $ repnme               <chr> "Attacking rural poverty : strategy and\n            public actions", "State policies and women's autonomy in\n      ...
# $ abstracts            <chr> "Poverty remains pervasive, and its\n            incidence and intensity are usually higher in rural than in\n       ...
# $ display_title        <chr> "Attacking rural poverty :\n            strategy and public actions", "State policies and women's\n            autono...
# $ listing_relative_url <chr> "/research/2000/12/1000476/attacking-rural-poverty-strategy-public-actions", "/research/2000/12/1000501/state-policie...
# $ docty                <chr> "Newsletter", "Working Paper (Numbered Series)", "Publication", "Poverty Reduction Strategy Paper (PRSP)", "Environme...
# $ subtopic             <chr> "Economic Theory & Research,Rural Settlements,Industrial Economics,Nutrition,Educational Sciences,Economic Growth,Agr...
# $ docna                <chr> "Attacking rural poverty : strategy and\n            public actions", "State policies and women's autonomy in\n      ...
# $ teratopic            <chr> "Poverty Reduction", "Education", "Energy", "Poverty Reduction", "Industry,Transport,Water Resources", NA, "Governanc...
# $ authors              <chr> "Okidegbe, Nwanze", "Zhang, Xiaodan", "Bogach, V. Susan", NA, "Carl Brothers International Inc.", "World Bank", "Mann...
# $ entityids            <chr> "000094946_01022305364180", "000094946_01022705322025", "000094946_01011005520622", "000094946_0102240538258", "00009...
# $ subsc                <chr> "Macro/Non-Trade", "Human Development", "(Historic)Other power and energy conversion", "(Historic)Macro/non-trade", "...
# $ lang                 <chr> "English", "English", "English", "English", "English", "Portuguese", "English", "English", "Chinese", "English", "Eng...
# $ historic_topic       <chr> "Poverty Reduction", "Education", "Energy", "Poverty Reduction", "Industry,Transport,Water Resources", NA, "Governanc...
# $ seccl                <chr> "Public", "Public", "Public", "Public", "Public", "Public", "Public", "Public", "Public", "Public", "Public", "Public...
# $ sectr                <chr> "(Historic)Economic Policy", "(Historic)Multisector", "(Historic)Electric Power & Other Energy", "(Historic)Economic ...
# $ majdocty             <chr> "Publications & Research", "Publications & Research", "Publications,Publications & Research", "Country Focus", "Proje...
# $ src_cit              <chr> "Rural development note. -- No. 6 (December 2000)", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N...
# $ keywd                <list> [[["Rural Poor;medium term expenditure\n            framework;rural poverty reduction strategy;rural\n            ar...
# $ owner                <chr> "Environ & Soc Sustainable Dev VP (ESD)", "Off of Sr VP Dev Econ/Chief Econ (DECVP)", "Energy & Mining Sector Unit (E...
# $ repnb                <chr> "21649", "21743", "WTP492", "21834", "E287", "27779", "21604", "E425", "21604", "22194", "21837", "22903", "E425", "E...
🌐
R Package
rdrr.io › r › base › list2DF.html
list2DF: Create Data Frame From List
## Create a data frame holding a list of character vectors and the ## corresponding lengths: x <- list(character(), "A", c("B", "C")) n <- lengths(x) list2DF(list(x = x, n = n)) ## Create data frames with no variables and the desired number of rows: list2DF() list2DF(nrow = 3L)