【问题标题】:How to revert one-hot encoded variable back into single column? [duplicate]如何将单热编码变量恢复为单列? [复制]
【发布时间】:2016-10-18 10:03:23
【问题描述】:

我有一个数据集:

data$a <- c(1,0,0,1,0)
data$b <- c(0,1,1,0,0)
data$c <- c(0,0,0,0,1)

我如何将其变成一个如下所示的分类列:

data$tranformed <- c(A,B,B,A,C)

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    你可以这样做:

    w <- which(data==1, arr.ind = T)
    data$tranformed <- toupper(names(data)[w[order(w[,1]),2]])
    
    #  a b c tranformed
    #1 1 0 0          A
    #2 0 1 0          B
    #3 0 1 0          B
    #4 1 0 0          A
    #5 0 0 1          C
    

    最好采用这种方式,因为它适用于列名并且字母不是硬编码的。如果更改列名,您将看到相应的更改。

    你甚至可以用更好的方式做到这一点:

    data$tranformed <- toupper(names(data)[max.col(data)])
    

    如果允许data 有没有任何1 的行,如下所示:

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

    你可以这样做:

    inds <- which(rowSums(data)==0)
    data$tranformed <- toupper(names(data)[max.col(data)])
    data$tranformed[inds] <- NA
    

    这会给你:

    #  a b c tranformed
    #1 1 0 0          A
    #2 0 1 0          B
    #3 0 0 0       <NA>
    #4 1 0 0          A
    #5 0 0 1          C
    

    【讨论】:

    • @ishido 查看我的更新
    • 一口气data$tranformed&lt;-ifelse(rowSums(df)&gt;=1,toupper(names(df)[max.col(df)]),NA)。比我的方法简单得多,做得好。
    • 非常优雅的解决方案!谢谢你们俩的分享。
    【解决方案2】:
    data$transformed<-factor(apply(data, 1, function(x) which(x == 1)),labels = colnames(data)) 
    

    或(小写字母)

    factor(LETTERS[apply(data, 1, function(x) which(x == 1))])
    

    编辑:如果有一行只有 0,如以下示例中的第 3 行。

    df=data.frame(a =c(1,0,0,1,0),
                   b=c(0,1,0,0,0),
                   c =c(0,0,0,0,1)
    )
      a b c
    1 1 0 0
    2 0 1 0
    3 0 0 0
    4 1 0 0
    5 0 0 1
    

    您不能使用上述解决方案,因为 apply 函数将输出长度为 0 的列表。
    解决方法:

    LETTERS[unlist(ifelse(sapply(apply(df, 1, function(x) which(x == 1)),length)==1,apply(df, 1, function(x) which(x == 1)),NA))]
    [1] "A" "B" NA  "A" "C"
    

    【讨论】:

    • 嗨,我使用了你的第一个建议,它奏效了。然后我尝试在下一个类别中使用它,但收到错误 data.lab$drinksubcat &lt;- factor(apply(data.lab[,35:46],1, function(x) which(x == 1)),labels = colnames(data.lab[,35:46])) Error in sort.list(y) : 'x' must be atomic for 'sort.list' Have you called 'sort' on a list? 你知道我为什么会得到这个吗?
    • 你能展示你的数据样本吗?
    • 我现在看到,对于该类别,有时没有一列有 1,而所有列都是 0。 data$LSM1 &lt;- c(0,1,1,1,0) data$LSM2 &lt;- c(1,0,0,0,0)一定是这个问题
    • 是的,这两种方法都不能只处理 0。在这种情况下,我会看看是否有办法输出 NA。
    • 查看我的编辑以了解处理这种情况的可能方法。
    猜你喜欢
    • 2019-11-06
    • 2016-07-04
    • 2021-01-21
    • 2018-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-09
    相关资源
    最近更新 更多