1. 程式人生 > >R|資料處理|list的轉化與轉置

R|資料處理|list的轉化與轉置

640?wx_fmt=gif作者簡介

Dwzb , R語言中文社群專欄作者,廈門大學統計專業學生。

知乎專欄:https://zhuanlan.zhihu.com/Data-AnalysisR 

本文講述思路如下

  • list 轉化為 data.frame(分為兩種情況)

  • data.frame 轉化為 list

  • matrix 轉化為 list

  • list的轉置

  • 參考資料

list 轉化為 data.frame

分為以下兩種情況

  • list 的每個元素作為一列

  • list 的每個元素作為一行(包括了list轉化為matrix的部分)

(1)list 的每個元素作為一列

下面程式碼的講述思路為

  • 先轉換最簡單的list(l)

  • 然後再讓list變複雜一些(ll),用多種方法進行轉換

  • 最後再複雜一點,編寫函式進行轉換

# 1.最簡單的list l <- list(1:4,2:5) as.data.frame(l) # 生成4*2的資料框 data.frame(l) # 結果同上 # 複雜一點 # 一個更復雜的list,兩層list,代表不同組別,需要分別轉化為資料框,然後拼接在一起 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包中的函式 library (plyr) df <- ldply (ll, data.frame) df # 三法,使用data.table包中的函式 library(data.table) ll0 <- list(a = list(x = 1:10, y = 2:11),           b = list(x = 11:20, y = 12:21)) rbindlist(ll0) # 此函式無法處理ll,因為無法迴圈對應 # 再複雜一點 # 如果其中有一列是我們不想要的,需要先提取再轉化為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)) # 如果直接使用這條命令,會報錯 # do.call(rbind,lapply(ll1, data.frame)) # 因為10不是3的倍數,無法迴圈對應,所以我們要把z這列去掉 f <- function(x){  data.frame(x[1:2]) } do.call(rbind,lapply(ll1, f))

(2)list 的每個元素作為一行

這裡的一些方法其實是先轉化成這樣的矩陣,再將矩陣轉化為資料框的,所以下文list轉化為矩陣的這部分就不再贅述

# 變成向量之後再轉化為矩陣,再轉化為資料框 df <- data.frame(matrix(unlist(l), nrow=2, byrow=T),stringsAsFactors=FALSE) df # 使用rbind.data.frame函式 # a <- rbind.data.frame(l) 不可以這樣使用 do.call(rbind.data.frame, l) # do.call 函式是將前面函式的引數放在一個list中使用,正好l是這樣一個list,它表示該函式的多個引數,而不是第一個引數是這個list # 用sapply將每一個元素變成向量,組成一個矩陣。下面兩種寫法等價 data.frame(t(sapply(l,c))) data.frame(t(sapply(l, `[`))) # 使用Reduce函式實現累加效果 data.frame(Reduce(rbind, l)) # 像累加一樣,每一個元素拿出來作為rbind的引數,和之前結合的結果再一次結合

data.frame 轉化為 list

我們要實現如下轉化

  • 每一列作為list的一個元素

  • 每一行作為list的一個元素

  • 對行進行分組,每一組作為list的一個元素

df <- data.frame(x=1:4,y=2:5,z=rep(1:2,2)) # 先看看list和as.list函式的結果是什麼樣的 as.list(df) # 每一列對應list的一個元素 list(df) # 一整個資料框成為list的一個元素 split(df, 1:4) # 每一行作為list的一個元素 split(df, df$z) # 按照z列進行分組

matrix 轉化為 list

我們想將matrix的每一行或者每一列作為list的一個元素,list 和 as.list 函式不能實現,前者是將整個矩陣作為list的一個元素,後者是將每一個值作為list的一個元素

我們使用如下方法實現這一過程

# matrix的每一列作為list的一個元素 mat <- matrix(c(1:4,2:5), byrow=F,ncol=2) # 下面每一行都可以實現 tapply(mat,rep(1:ncol(mat),each=nrow(mat)),function(i)i) # 分組計算生成一個list split(mat, rep(1:ncol(mat), each = nrow(mat))) split(mat, col(mat)) # 更簡潔的寫法 as.list(as.data.frame(mat)) # 速度比較慢 lapply(seq_len(ncol(mat)), function(i) mat[,i]) plyr::alply(mat,2) # matrix的每一行作為list的一個元素 # 一種方法是將mat轉置之後用上面的方法,還有下面兩種方法 split(mat, row(mat)) lapply(seq_len(nrow(mat)), function(i) mat[i,])

list 的轉置

這部分對兩個型別的list進行轉置

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 # 實現將 before 轉換成after形式,其實就是對列表進行轉置 # 另外一個例子,list 中的元素是向量而不是list l <- list(1:4,1:4)

下面使用幾種方法實現

# 第一種方法,使用 data.table 和 purrr 包中現成的函式 # data.table::transpose(before) # 處理不了 purrr::transpose(before) data.table::transpose(l) # list 的每個元素是向量 purrr::transpose(l) # list的每個元素還是list # 第二種方法,自己編寫函式 # 下面兩行結果和 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 的元素組合在一起了 # 第三種方法,轉化為資料框 # 使用更靈活的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) # 這時可以用data.frame as.list(data.table(t(dt))) # 使用data.frame也可以,但是要先轉化為矩陣 new <- do.call(rbind, before) as.list(data.frame(new))

文末彩蛋

最後一次推薦 rstudio 快捷鍵

  • ctrl + up/down 上下滾動介面

  • ctrl + enter 執行該行程式,同時游標換行換行

  • alt + enter 執行該行程式,游標不換行

更多快捷鍵在 rstudio 選單欄中的 help-keyboard shortcuts help 中查詢

往期回顧

640?wx_fmt=jpeg

公眾號後臺回覆關鍵字即可學習

回覆 爬蟲            爬蟲三大案例實戰  
回覆 
Python1小時破冰入門

回覆 資料探勘     R語言入門及資料探勘
回覆 
人工智慧     三個月入門人工智慧
回覆 資料分析師  資料分析師成長之路 
回覆 機器學習      機器學習的商業應用
回覆 資料科學      資料科學實戰
回覆 常用演算法      常用資料探勘演算法