简体   繁体   English

将表的命名列表转换为data.frame

[英]Transform named list of tables into data.frame

I have a named list of table s like this: 我有一个这样的table的命名list

# make this simple and reproducible
set.seed(1)
days <- c("mon", "tue", "wed", "thu", "fri", "sat", "sun")

# create list of tables
mylist <- list(
  one = table(sample(days, 3, replace = TRUE)),
  two = table(sample(days, 5, replace = TRUE)),
  three = table(NULL),
  four = table(sample(days, 4, replace = TRUE))
)

    mylist
#$one
#
#fri tue wed 
#  1   1   1 
#
#$two
#
#fri sun tue 
#  1   3   1 
#
#$three
#< table of extent 0 >
#
#$four
#
#fri mon tue 
#  1   1   2 

And I would like to transform it into this data.frame where all the original list elements are rows in the resulting data.frame : 我想将其转换为data.frame ,其中所有原始列表元素都是结果data.frame中的行:

mydf
#      mon tue wed fri sun
#one     0   1   1   1   0
#two     0   1   0   1   3
#three   0   0   0   0   0
#four    1   2   0   1   0

# In this case I cheated and created it manually (order of columns is not important, order of rows is ideally preserved):
mydf <- data.frame(
  mon = c(0, 0, 0, 1),
  tue = c(1, 1, 0, 2),
  wed = c(1, 0, 0, 0),
  fri = c(1, 1, 0, 1),
  sun = c(0, 3, 0, 0)
)
rownames(mydf) <- c("one", "two", "three", "four")

I'm aware this is probably a non-standard transformation - is there any way to do this? 我知道这可能是非标准的转换-有没有办法做到这一点?

EDIT: It might be relevant to know that the raw data would look something like this: raw <- c("one:tue,wed,fri", "two:fri,sun,sun,tue,sun", "three", "four:tue,mon,tue,fri") 编辑:可能需要知道原始数据看起来像这样: raw <- c("one:tue,wed,fri", "two:fri,sun,sun,tue,sun", "three", "four:tue,mon,tue,fri")

Thanks! 谢谢!

We can use rbindlist 我们可以使用rbindlist

library(data.table)
rbindlist(lapply(mylist, as.data.frame.list), fill=TRUE)

Or using melt/acast from reshape2 或者使用melt/acastreshape2 melt/acast reshape2

library(reshape2)
acast(melt(mylist), L1~Var1, value.var="value", fill=0)

Here's a solution using dplyr and tidyr : 这是使用dplyrtidyr的解决方案:

library(dplyr)
library(tidyr)
mylist2 <- mylist %>%
  lapply(., function(i) spread(as.data.frame(i), Var1, Freq)) %>%
  bind_rows() %>%
  mutate_all(funs(ifelse(is.na(.), 0, .)))

Result: 结果:

> mylist2
  fri mon tue sun wed thu
1   1   1   1   0   0   0
2   0   1   0   1   3   0
3   1   0   1   0   0   2

Building on @alexis_laz comment I ended up using this solution: 基于@alexis_laz注释,我最终使用了以下解决方案:

dat <- read.table(text = raw, sep = ":", fill = TRUE, na.strings = "", stringsAsFactors = FALSE)
dat <- as.data.frame.matrix(t(table(stack(setNames(strsplit(dat$V2, ",", TRUE), dat$V1)))))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM