Home > other >  From list of list, to dataframe with column of lists
From list of list, to dataframe with column of lists

Time:04-23

I have data as follows:

dat <- structure(
    list( 
        freq = list(a= c(5, 38, 43, 27, 44, 20, 177), b=c(3, 5, 12, 53, 73))), 
    row.names = c("A", "B"), class = "data.frame")

The only thing I want to do is to get a column with the list names, and a column with the lists:

data.frame:
   rn  values
1. A   c(5, 38, 43, 27, 44, 20, 177)
2. B   c(3, 5, 12, 53, 73)

But I just cannot figure it out..

How should this be done?

CodePudding user response:

Use names:

dat$rn <- names(dat$freq)
dat

#                        freq rn
#A 5, 38, 43, 27, 44, 20, 177  a
#B           3, 5, 12, 53, 73  b

You can also use rownames_to_column:

tibble::rownames_to_column(dat, "rn")
#  rn                       freq
#1  A 5, 38, 43, 27, 44, 20, 177
#2  B           3, 5, 12, 53, 73

CodePudding user response:

We can use imap

library(purrr)
imap_dfr(dat$freq, ~ tibble(rn = toupper(.y), values = list(.x)))

-output

# A tibble: 2 × 2
  rn    values   
  <chr> <list>   
1 A     <dbl [7]>
2 B     <dbl [5]>

Or with enframe

library(tibble)
enframe(dat$freq)
# A tibble: 2 × 2
  name  value    
  <chr> <list>   
1 a     <dbl [7]>
2 b     <dbl [5]>

CodePudding user response:

An alternative of rownames_to_column() in tibble is to set the arg rownames of as_tibble().

tibble::as_tibble(dat, rownames = "rn")

# A tibble: 2 × 2
  rn    freq        
  <chr> <named list>
1 A     <dbl [7]>   
2 B     <dbl [5]>

CodePudding user response:

Use cbind

cbind(rn=rownames(dat), dat[1])
#   rn                       freq
# A  A 5, 38, 43, 27, 44, 20, 177
# B  B           3, 5, 12, 53, 73

BTW, here is a complete solution to your initial problem.

res <- apply(dat_in[-c(1, length(dat_in))], 1, \(x) list2DF(list(unname(x[x != 0])))) |> 
  list2DF() |> t() |> as.data.frame() |> cbind(dat_in$rn) |> subset(select=2:1) |>
  setNames(c('rn', 'values'))
res
#   rn                values
# 1  W 5, 38, 43, 27, 44, 20
# 2  M          3, 5, 12, 53

where

str(res)
# 'data.frame': 2 obs. of  2 variables:
# $ rn    : chr  "W" "M"
# $ values:List of 2
#  ..$ 1: int  5 38 43 27 44 20
#  ..$ 2: int  3 5 12 53

Data:

dat_in <- structure(list(rn = c("W", "M"), `      0` = c(0L, 0L), `[      0,     25)` = c(5L, 
0L), `[     25,     50)` = c(0L, 0L), `[     25,    100)` = c(38L, 
3L), `[     50,    100)` = c(0L, 0L), `[    100,    250)` = c(43L, 
5L), `[    100,    500)` = c(0L, 0L), `[    250,    500)` = c(27L, 
12L), `[    500,   1000)` = c(44L, 0L), `[    500,1000000]` = c(0L, 
53L), `[   1000,   1500)` = c(0L, 0L), `[   1000,1000000]` = c(20L, 
0L), `[   1500,   3000)` = c(0L, 0L), `[   3000,1000000]` = c(0L, 
0L), Sum_col = c(177, 73)), row.names = 1:2, class = c("data.table", 
"data.frame"))
  • Related