本文講述思路如下 list 轉(zhuǎn)化為 data.frame分為以下兩種情況 (1)list 的每個(gè)元素作為一列 下面代碼的講述思路為 先轉(zhuǎn)換最簡(jiǎn)單的list(l) 然后再讓list變復(fù)雜一些(ll),用多種方法進(jìn)行轉(zhuǎn)換 最后再?gòu)?fù)雜一點(diǎn),編寫函數(shù)進(jìn)行轉(zhuǎn)換
# 1.最簡(jiǎn)單的list
l <- list(1:4,2:5)
as.data.frame(l) # 生成4*2的數(shù)據(jù)框
data.frame(l) # 結(jié)果同上
# 復(fù)雜一點(diǎn)
# 一個(gè)更復(fù)雜的list,兩層list,代表不同組別,需要分別轉(zhuǎn)化為數(shù)據(jù)框,然后拼接在一起
ll <- list(a = list(x = 1:10, y = 2:11, group = 1),
b = list(x = 11:20, y = 12:21, group = 2))
# 一法
dfll <- do.call(rbind,lapply(ll, data.frame))
dfll
# 二法,使用plyr包中的函數(shù)
library (plyr)
df <- ldply (ll, data.frame)
df
# 三法,使用data.table包中的函數(shù)
library(data.table)
ll0 <- list(a = list(x = 1:10, y = 2:11),
b = list(x = 11:20, y = 12:21))
rbindlist(ll0) # 此函數(shù)無法處理ll,因?yàn)闊o法循環(huán)對(duì)應(yīng)
# 再?gòu)?fù)雜一點(diǎn)
# 如果其中有一列是我們不想要的,需要先提取再轉(zhuǎn)化為data.frame
ll1 <- list(a = list(x = 1:10, y = 2:11, z = 1:3),
b = list(x = 11:20, y = 12:21, z = 1:3))
# 如果直接使用這條命令,會(huì)報(bào)錯(cuò)
# do.call(rbind,lapply(ll1, data.frame))
# 因?yàn)?0不是3的倍數(shù),無法循環(huán)對(duì)應(yīng),所以我們要把z這列去掉
f <- function(x){
data.frame(x[1:2])
}
do.call(rbind,lapply(ll1, f))
(2)list 的每個(gè)元素作為一行 這里的一些方法其實(shí)是先轉(zhuǎn)化成這樣的矩陣,再將矩陣轉(zhuǎn)化為數(shù)據(jù)框的,所以下文list轉(zhuǎn)化為矩陣的這部分就不再贅述 # 變成向量之后再轉(zhuǎn)化為矩陣,再轉(zhuǎn)化為數(shù)據(jù)框
df <- data.frame(matrix(unlist(l), nrow=2, byrow=T),stringsAsFactors=FALSE)
df
# 使用rbind.data.frame函數(shù)
# a <- rbind.data.frame(l) 不可以這樣使用
do.call(rbind.data.frame, l) # do.call 函數(shù)是將前面函數(shù)的參數(shù)放在一個(gè)list中使用,正好l是這樣一個(gè)list,它表示該函數(shù)的多個(gè)參數(shù),而不是第一個(gè)參數(shù)是這個(gè)list
# 用sapply將每一個(gè)元素變成向量,組成一個(gè)矩陣。下面兩種寫法等價(jià)
data.frame(t(sapply(l,c)))
data.frame(t(sapply(l, `[`)))
# 使用Reduce函數(shù)實(shí)現(xiàn)累加效果
data.frame(Reduce(rbind, l)) # 像累加一樣,每一個(gè)元素拿出來作為rbind的參數(shù),和之前結(jié)合的結(jié)果再一次結(jié)合
data.frame 轉(zhuǎn)化為 list我們要實(shí)現(xiàn)如下轉(zhuǎn)化 df <- data.frame(x=1:4,y=2:5,z=rep(1:2,2))
# 先看看list和as.list函數(shù)的結(jié)果是什么樣的
as.list(df) # 每一列對(duì)應(yīng)list的一個(gè)元素
list(df) # 一整個(gè)數(shù)據(jù)框成為list的一個(gè)元素
split(df, 1:4) # 每一行作為list的一個(gè)元素
split(df, df$z) # 按照z列進(jìn)行分組
matrix 轉(zhuǎn)化為 list我們想將matrix的每一行或者每一列作為list的一個(gè)元素,list 和 as.list 函數(shù)不能實(shí)現(xiàn),前者是將整個(gè)矩陣作為list的一個(gè)元素,后者是將每一個(gè)值作為list的一個(gè)元素 我們使用如下方法實(shí)現(xiàn)這一過程 # matrix的每一列作為list的一個(gè)元素
mat <- matrix(c(1:4,2:5), byrow=F,ncol=2)
# 下面每一行都可以實(shí)現(xiàn)
tapply(mat,rep(1:ncol(mat),each=nrow(mat)),function(i)i) # 分組計(jì)算生成一個(gè)list
split(mat, rep(1:ncol(mat), each = nrow(mat)))
split(mat, col(mat)) # 更簡(jiǎn)潔的寫法
as.list(as.data.frame(mat)) # 速度比較慢
lapply(seq_len(ncol(mat)), function(i) mat[,i])
plyr::alply(mat,2)
# matrix的每一行作為list的一個(gè)元素
# 一種方法是將mat轉(zhuǎn)置之后用上面的方法,還有下面兩種方法
split(mat, row(mat))
lapply(seq_len(nrow(mat)), function(i) mat[i,])
list 的轉(zhuǎn)置這部分對(duì)兩個(gè)類型的list進(jìn)行轉(zhuǎn)置 ax <- data.frame(a=1,x=2)
ay <- data.frame(a=3,y=4)
bw <- data.frame(b=5,w=6)
bz <- data.frame(b=7,z=8)
before <- list( a=list(x=ax, y=ay), b=list(w=bw, z=bz))
after <- list(w.x=list(a=ax, b=bw), y.z=list(a=ay, b=bz))
before
after
# 實(shí)現(xiàn)將 before 轉(zhuǎn)換成after形式,其實(shí)就是對(duì)列表進(jìn)行轉(zhuǎn)置
# 另外一個(gè)例子,list 中的元素是向量而不是list
l <- list(1:4,1:4)
下面使用幾種方法實(shí)現(xiàn) # 第一種方法,使用 data.table 和 purrr 包中現(xiàn)成的函數(shù)
# data.table::transpose(before) # 處理不了
purrr::transpose(before)
data.table::transpose(l) # list 的每個(gè)元素是向量
purrr::transpose(l) # list的每個(gè)元素還是list
# 第二種方法,自己編寫函數(shù)
# 下面兩行結(jié)果和 purrr::transpose 相同
lapply(1:2, function(i) lapply(before, "[[", i))
lapply(1:4, function(i) lapply(l, "[[", i))
lapply(1:4, function(i) sapply(l, "[[", i)) # 和 data.table::transpose 一樣
lapply(1:2, function(i) sapply(before, "[[", i)) # 將 list 的元素組合在一起了
# 第三種方法,轉(zhuǎn)化為數(shù)據(jù)框
# 使用更靈活的data.table
dt = as.data.table(before)
as.list(data.table(t(dt)))
dt = as.data.table(l)
as.list(data.table(t(dt)))
dt = as.data.frame(l) # 這時(shí)可以用data.frame
as.list(data.table(t(dt)))
# 使用data.frame也可以,但是要先轉(zhuǎn)化為矩陣
new <- do.call(rbind, before)
as.list(data.frame(new))
|