【问题标题】:Convert Character Matrix to TRUE/FALSE Matrix based on column names根据列名将字符矩阵转换为真/假矩阵
【发布时间】:2015-07-21 18:53:24
【问题描述】:

我有一个如下格式的数据框

    1 2 a b c
1   a b 0 0 0
2   b   0 0 0
3   c   0 0 0

我想用 TRUE/FALSE 填充 a 到 c 列,说明列名是在第 1 列还是第 2 列中

    1 2 a b c
1   a b 1 1 0
2   b   0 1 0
3   c   0 0 1

我有一个包含大约 530,000 条记录、4 个描述列和 95 个输出列的数据集,因此 for 循环不起作用。我尝试了以下格式的代码,但是太耗时了:

> for(i in 3:5) {   
>   for(j in 1:3) {
>     for(k in 1:2){
>       if(df[j,k]==colnames(df)[i]) df[j, i]=1
>     }   
>   } 
> }

有没有更简单、更有效的方法来实现相同的输出?

提前致谢!

【问题讨论】:

    标签: r


    【解决方案1】:

    一个选项是mtabulate 来自qdapTools

    library(qdapTools)
    df1[-(1:2)] <- mtabulate(as.data.frame(t(df1[1:2])))[-3]
    df1
    #  1 2 a b c
    #1 a b 1 1 0
    #2 b   0 1 0
    #3 c   0 0 1
    

    或者我们melt转换为matrix后的数据集,使用table获取频率,并将输出分配给数字列。

    library(reshape2)
    df1[-(1:2)] <- table(melt(as.matrix(df1[1:2]))[-2])[,-1]
    

    或者我们可以“粘贴”前两列并使用cSplit_e 来获取二进制格式。

    library(splitstackshape)
    cbind(df1[1:2], cSplit_e(as.data.table(do.call(paste, df1[1:2])),
                       'V1', ' ', type='character', fill=0, drop=TRUE))
    

    数据

    df1 <- structure(list(`1` = c("a", "b", "c"), `2` = c("b", "", ""), 
    a = c(0L, 0L, 0L), b = c(0L, 0L, 0L), c = c(0L, 0L, 0L)), .Names = c("1", 
    "2", "a", "b", "c"), class = "data.frame", row.names = c("1", 
    "2", "3"))
    

    【讨论】:

    • 感谢您及时周到的回复。对于如此庞大的数据集,“melt”选项最终运行得非常快。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-14
    • 2018-03-01
    • 2019-12-14
    • 1970-01-01
    • 2020-05-14
    • 1970-01-01
    • 2010-12-03
    相关资源
    最近更新 更多