从列表中创建频率数据框,同时维护 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