打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
list的提取和转化

本文讲述思路如下

  • list 转化为 data.frame(分为两种情况)

  • data.frame 转化为 list

  • matrix 转化为 list

  • list的转置

  • 参考资料

list 转化为 data.frame

分为以下两种情况

  • list 的每个元素作为一列

  • list 的每个元素作为一行(包括了list转化为matrix的部分)

(1)list 的每个元素作为一列

下面代码的讲述思路为

  • 先转换最简单的list(l)

  • 然后再让list变复杂一些(ll),用多种方法进行转换

  • 最后再复杂一点,编写函数进行转换

# 1.最简单的listl <- 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.framell1 <- 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) # 分组计算生成一个listsplit(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))beforeafter# 实现将 before 转换成after形式,其实就是对列表进行转置# 另外一个例子,list 中的元素是向量而不是listl <- 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.tabledt = 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.frameas.list(data.table(t(dt)))# 使用data.frame也可以,但是要先转化为矩阵new <- do.call(rbind, before) as.list(data.frame(new))
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
R语言apply函数族笔记
Reduce函数实现多个数据框批量合并
R语言 data.frame 大全
R学习:环境和函数
R数据分析:apply()的各种变体你分清了吗?
不明白为什么同一个癌症不同病人的表型信息列不一致
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服