【问题标题】:Make a frequency data frame from a list while maintaining rows in R从列表中创建频率数据框,同时维护 R 中的行
【发布时间】:2015-06-21 01:08:02
【问题描述】:

我有一个如下所示的列表:

>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”包的文档,但我没有任何运气。任何帮助表示赞赏。谢谢。

【问题讨论】:

    标签: r plyr reshape2


    【解决方案1】:

    你可以从qdapTools试试mtabulate

    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
    

    【讨论】:

      【解决方案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
      

      【讨论】:

        【解决方案3】:

        我不认为这是最优雅的,但它确实有效。

        您的数据:

        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"      
        

        【讨论】:

        • 以类似的精神,但也许更容易do.call(rbind, lapply(AP, function(ii) table(factor(ii, levels=unique(unlist(AP))))))
        猜你喜欢
        • 1970-01-01
        • 2018-09-21
        • 1970-01-01
        • 2021-07-01
        • 1970-01-01
        • 2016-11-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多