Convert List to Data Frame While Keeping List-Element Names

Convert list to data frame while keeping list-element names

Here is one way:

## your list
ll <- list("1" = 1:2, "2" = 1:3, "3" = 1:2)
## convert to data.frame
dl <- data.frame(ID = rep(names(ll), sapply(ll, length)),
Obs = unlist(ll))

This gives:

> dl
ID Obs
11 1 1
12 1 2
21 2 1
22 2 2
23 2 3
31 3 1
32 3 2

The first line in the data.frame() call is just some code to repeat the names() of the list the required number of times. The second line just unlists the list converting it into a vector.

Convert elements of list to dataframe keeping column names unchanged

In the OP's code, change the [ to [[ as the first is still a list of length 1 and have a list name as well, while the second [[ extracts the list element. So, naturally, when we do the as.data.frame, the list element names also gets appended while flattening that element

for (i in seq_along(mylist)) {
assign(paste("df_",names(mylist[[i]]),sep = ""), mylist[[i]],
col.names = names(dfi)))
}
names(df_april)

NOTE: It is better not to create mutiple objects in the global env.

Putting row names and column names when converting from list to data frame

In LWfunction return a 1-row dataframe with all the required values in it.

library(FSA)
library(FSAdata)
library(dplyr)
library(tidyr)

LWfunction <- function(x) {
fits <- lm(log(weight) ~ log(length), data = x)
a <- hoCoef(fits, 2,3)
b <- confint(fits)
output <- cbind(a, data.frame(intercept_2.5 = b[1, 1],
intercept_97.5 = b[1, 2],
log_length_2.5 = b[2, 1],
log_length_97.5 = b[2, 2]))
return(output)
}

apply it for each year and month :

result <- data %>%
group_by(month, year) %>%
summarise(output = list(LWfunction(cur_data()))) %>%
ungroup %>%
unnest(output)

result
# A tibble: 7 x 13
# month year term `Ho Value` Estimate `Std. Error` T df
# <int> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 4 1992 2 3 3.00 0.0396 0.0216 58
#2 5 1992 2 3 2.88 0.0315 -3.78 64
#3 6 1992 2 3 2.86 0.0317 -4.43 152
#4 7 1992 2 3 2.87 0.0189 -7.11 147
#5 8 1992 2 3 2.89 0.0312 -3.40 67
#6 9 1992 2 3 3.02 0.0326 0.680 114
#7 10 1992 2 3 3.00 0.0314 -0.113 64
# … with 5 more variables: `p value` <dbl>, intercept_2.5 <dbl>,
# intercept_97.5 <dbl>, log_length_2.5 <dbl>,
# log_length_97.5 <dbl>

Convert a list to a data frame

Update July 2020:

The default for the parameter stringsAsFactors is now default.stringsAsFactors() which in turn yields FALSE as its default.


Assuming your list of lists is called l:

df <- data.frame(matrix(unlist(l), nrow=length(l), byrow=TRUE))

The above will convert all character columns to factors, to avoid this you can add a parameter to the data.frame() call:

df <- data.frame(matrix(unlist(l), nrow=132, byrow=TRUE),stringsAsFactors=FALSE)

Keep all names from list to data.frame

A possible solution is to create a function that converts the list into a data frame with as.data.frame() and then sets the names to the desired values in a second step:

list_df <- function(list) {
df <- as.data.frame(list)
names(df) <- list_names(list)
return (df)
}

Obviously, defining list_names() is the hard part. One possibility is to recurse through the nested lists:

list_names <- function(list) {

recursor <- function(list, names) {
if (is.list(list)) {
new_names <- paste(names, names(list), sep = ".")
out <- unlist(mapply(list, new_names, FUN = recursor))
} else {
out <- names
}
return(out)
}

new_names <- unlist(mapply(list, names(list), FUN = recursor))
return(new_names)
}

This works for your two examples:

l <- list(a = list(b = 1), c = 2)
ll <- list(a = list(b = 1, bb = 1), c = 2)
list_df(l)
## a.b c
## 1 1 2
list_df(ll)
## a.b a.bb c
## 1 1 1 2

It also works for a list that is not nested, as well as for a list with deeper nesting:

ls <- list(a = 1, b = 3)
lc <- list(a = list(b = 1, bb = 1), c = 2, d = list(e = list(f = 1, ff = 2), ee = list(fff = 5)))
list_df(ls)
## a b
## 1 1 3
list_df(lc)
## a.b a.bb c d.e.f d.e.ff d.ee.fff
## 1 1 1 2 1 2 5

How to convert list of lists into a dataframe while keeping track of list number innR?

Or, we can simply utilize data.table::rbindlist() function:

library(data.table)

rbindlist(df_list, idcol = 'count')

# count replicate level high.density low.density
# 1: 1 1 low 14 31
# 2: 1 1 low 14 31
# 3: 1 2 low 12 45
# 4: 1 2 low 12 45
# 5: 1 1 mid 24 NA
# ---
# 10996: 1000 2 mid NA 17
# 10997: 1000 2 mid NA 17
# 10998: 1000 2 up 20 10
# 10999: 1000 2 up 20 5
# 11000: 1000 2 up 40 2

Convert list to dataframe in R and add column with names of sub-lists

Another option is to use stack after setting the name for each element of the list to be the vector:

stack(setNames(l, n))

# values ind
#1 a one
#2 b one
#3 c two
#4 d two
#5 e two
#6 e three

Convert LIst To Dataframe Using For Loop And Saving Under Different Names In R

If you have list of dataframes in list, you can name them and then use list2env to have them as separate dataframes in the environment.

names(list) <- paste0('df', seq_along(list))
list2env(list, .GlobalEnv)

Using a reproducible exmaple,

temp <- list(mtcars, mtcars)
names(temp) <- paste0('df', seq_along(temp))
list2env(temp, .GlobalEnv)

head(df1)
# mpg cyl disp hp drat wt qsec vs am gear carb
#Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
#Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
#Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
#Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
#Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
#Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1

head(df2)
# mpg cyl disp hp drat wt qsec vs am gear carb
#Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
#Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
#Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
#Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
#Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
#Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1

However, note that

  • list is an internal function in R, so it is better to name your variables something else.
  • As @MrFlick suggested try to keep your data in a list as lists are easier to manage rather than creating numerous objects in your global environment.

R List of lists to dataframe with list name as extra column

This might work

library(purrr)
ans <- map_df(past_earnings_lists, ~as.data.frame(.x), .id="id")

It uses map_df, which will map over lists and convert the result to data frames (if possible). Use the .id argument to add names to each data frame as a column.



Related Topics



Leave a reply



Submit