从列表中创建频率数据框,同时维护 R 中的行
Make a frequency data frame from a list while maintaining rows in R
我有一个如下所示的列表:
>AP
$CMP1
[1] 411050384 411050456 411050456 411058568
$CMP2
[1] 411050384 411050456
$CMP3
[1] 411050384 411050456 411058568 428909002 428909002
并且我想将列表转换为一个数据框,该数据框使用每个唯一条目作为列名,并且数据框中的条目是列表每个成员的频率计数 "CMP"。这就是我希望数据框的样子。
411050384 411050456 411058568 428909002
CMP1 1 2 1 0
CMP2 1 1 0 0
CMP3 1 1 1 2
我已经查看了 'plyr' 和 'reshape2' 包的文档,但没有任何运气。任何帮助表示赞赏。谢谢
我不认为这是最优雅的,但它确实有效。
您的数据:
CMP1=c(411050384, 411050456, 411050456, 411058568)
CMP2=c(411050384, 411050456)
CMP3=c(411050384, 411050456, 411058568, 428909002, 428909002)
AP=list(CMP1, CMP2, CMP3)
names(AP)=c('CMP1', 'CMP2', 'CMP3')
首先对列表的每个元素使用table
来获取频率。然后我使用 Map
将列表中每个元素的名称添加为变量,并使用 rbind
将它们放在一起。
x<-lapply(lapply(AP, table), cbind)
x<-Map(cbind, x, id = names(AP))
x1<-do.call('rbind',x)
我制作了一个没有因素的数据框,以使最终矩阵更容易:
df<-data.frame(x=x1[,2], y=rownames(x1), z=x1[,1], stringsAsFactors = F)
使用 reshape2
获取矩阵。
mat <- reshape2::acast(df, x~y, value.var="z", fill=0)
mat
411050384 411050456 411058568 428909002
CMP1 "1" "2" "1" "0"
CMP2 "1" "1" "0" "0"
CMP3 "1" "1" "1" "2"
这个呢?
res <- t(sapply(AP, function(y) sapply(unique(unlist(AP)), function(x) sum(x == y))))
colnames(res) <- unique(unlist(AP))
res
411050384 411050456 411058568 428909002
CMP1 1 2 1 0
CMP2 1 1 0 0
CMP3 1 1 1 2
您可以尝试 mtabulate
来自 qdapTools
library(qdapTools)
mtabulate(AP)
# 411050384 411050456 411058568 428909002
#CMP1 1 2 1 0
#CMP2 1 1 0 0
#CMP3 1 1 1 2
或 melt/acast
来自 reshape2
library(reshape2)
acast(melt(AP), L1~value, length)
# 411050384 411050456 411058568 428909002
#CMP1 1 2 1 0
#CMP2 1 1 0 0
#CMP3 1 1 1 2
或使用base R
table(stack(AP)[2:1])
# values
#ind 411050384 411050456 411058568 428909002
# CMP1 1 2 1 0
# CMP2 1 1 0 0
# CMP3 1 1 1 2
我有一个如下所示的列表:
>AP
$CMP1
[1] 411050384 411050456 411050456 411058568
$CMP2
[1] 411050384 411050456
$CMP3
[1] 411050384 411050456 411058568 428909002 428909002
并且我想将列表转换为一个数据框,该数据框使用每个唯一条目作为列名,并且数据框中的条目是列表每个成员的频率计数 "CMP"。这就是我希望数据框的样子。
411050384 411050456 411058568 428909002
CMP1 1 2 1 0
CMP2 1 1 0 0
CMP3 1 1 1 2
我已经查看了 'plyr' 和 'reshape2' 包的文档,但没有任何运气。任何帮助表示赞赏。谢谢
我不认为这是最优雅的,但它确实有效。
您的数据:
CMP1=c(411050384, 411050456, 411050456, 411058568)
CMP2=c(411050384, 411050456)
CMP3=c(411050384, 411050456, 411058568, 428909002, 428909002)
AP=list(CMP1, CMP2, CMP3)
names(AP)=c('CMP1', 'CMP2', 'CMP3')
首先对列表的每个元素使用table
来获取频率。然后我使用 Map
将列表中每个元素的名称添加为变量,并使用 rbind
将它们放在一起。
x<-lapply(lapply(AP, table), cbind)
x<-Map(cbind, x, id = names(AP))
x1<-do.call('rbind',x)
我制作了一个没有因素的数据框,以使最终矩阵更容易:
df<-data.frame(x=x1[,2], y=rownames(x1), z=x1[,1], stringsAsFactors = F)
使用 reshape2
获取矩阵。
mat <- reshape2::acast(df, x~y, value.var="z", fill=0)
mat
411050384 411050456 411058568 428909002
CMP1 "1" "2" "1" "0"
CMP2 "1" "1" "0" "0"
CMP3 "1" "1" "1" "2"
这个呢?
res <- t(sapply(AP, function(y) sapply(unique(unlist(AP)), function(x) sum(x == y))))
colnames(res) <- unique(unlist(AP))
res
411050384 411050456 411058568 428909002
CMP1 1 2 1 0
CMP2 1 1 0 0
CMP3 1 1 1 2
您可以尝试 mtabulate
来自 qdapTools
library(qdapTools)
mtabulate(AP)
# 411050384 411050456 411058568 428909002
#CMP1 1 2 1 0
#CMP2 1 1 0 0
#CMP3 1 1 1 2
或 melt/acast
来自 reshape2
library(reshape2)
acast(melt(AP), L1~value, length)
# 411050384 411050456 411058568 428909002
#CMP1 1 2 1 0
#CMP2 1 1 0 0
#CMP3 1 1 1 2
或使用base R
table(stack(AP)[2:1])
# values
#ind 411050384 411050456 411058568 428909002
# CMP1 1 2 1 0
# CMP2 1 1 0 0
# CMP3 1 1 1 2