【问题标题】:Condensing/combining multiple columns with same name and logical values压缩/组合具有相同名称和逻辑值的多个列
【发布时间】:2014-02-22 01:54:16
【问题描述】:

我正在尝试压缩具有同一列多次的data.frame。要压缩的列具有逻辑值。

data.frame 看起来像这样:

mydf <- data.frame (ID = c("1A", "2A", "3A", "1B", "2B", "3B"),
                A = c("N1", "N2", "N3", "N4", "N5", "N6"),
                AA = c(T, T, F, F, F, F),
                BB = c(T, T, F, F, F, F),
                AA = c(T, F, T, F, F, F),
                CC = c(T, F, T, F, T, F),
                DD = c(T, F, T, F, T, T),
                AA = c(F, F, F, F, T, F),
                EE = c(F, F, T, T, T, F),
                AA = c(F, F, F, F, F, F), check.names = FALSE)

如果一行中的所有AA 列至少设置为TRUE,我想压缩AA,将压缩列设置为TRUE。例如,在1A 行中,AA 列具有TRUETRUEFALSEFALSE 的序列。这意味着压缩列,我们称之为 ZZ,应该在行 1A 中有 TRUE,但在行 3B 中应该有 FALSE

所需的输出如下所示:

mydfnew <- data.frame (ID = c("1A", "2A", "3A", "1B", "2B", "3B"),
                A = c("N1", "N2", "N3", "N4", "N5", "N6"),
                AA = c(T, T, T, F, T, F),
                BB = c(T, T, F, F, F, F),
                CC = c(T, F, T, F, T, F),
                DD = c(T, F, T, F, T, T),
                EE = c(F, F, T, T, T, F))

AA 列被压缩的ZZ 列替换,该列再次称为 AA。我现在知道如何调用 AA 列,并且有多个这样的“重复”列。我希望这是有道理的。

任何帮助和指点将不胜感激。

【问题讨论】:

    标签: r dataframe conditional combinations multiple-columns


    【解决方案1】:

    所有列的解决方案(前两列除外):

    res <- tapply(names(mydf)[-(1:2)], names(mydf)[-(1:2)], FUN = function(n)
            as.logical(rowSums(mydf[names(mydf) %in% n[1]]))) 
    
    cbind(mydf[1:2], do.call(cbind, res))
    
    
      ID  A    AA    BB    CC    DD    EE
    1 1A N1  TRUE  TRUE  TRUE  TRUE FALSE
    2 2A N2  TRUE  TRUE FALSE FALSE FALSE
    3 3A N3  TRUE FALSE  TRUE  TRUE  TRUE
    4 1B N4 FALSE FALSE FALSE FALSE  TRUE
    5 2B N5  TRUE FALSE  TRUE  TRUE  TRUE
    6 3B N6 FALSE FALSE FALSE  TRUE FALSE
    

    【讨论】:

    • 非常感谢。完美地处理我的数据,因为第一列是识别列。
    【解决方案2】:

    叮叮叮!

    l <- sapply(df, is.logical)
    
    cbind(df[!l], lapply(split(as.list(df[l]), names(df)[l]), Reduce, f = `|`))
    

    【讨论】:

    • 这让我很困惑,但它在我的 data.frame 上工作了 10.000 列。由于其简单性和效率,我已将其作为我接受的答案。非常感谢!
    【解决方案3】:

    作为开始:

    rowSums(mydf[,colnames(mydf) == 'AA']) > 0
    

    【讨论】:

      【解决方案4】:

      基本上是@SvenHohenstein 解决方案的一种变体:

      unq <- unique(names(mydf)[-(1:2)])
      res <- setNames(lapply(unq, function(x) rowSums(mydf[names(mydf)==x])>0 ),unq)
      cbind(mydf[1:2],res)
      
      #  ID  A    AA    BB    CC    DD    EE
      #1 1A N1  TRUE  TRUE  TRUE  TRUE FALSE
      #2 2A N2  TRUE  TRUE FALSE FALSE FALSE
      #3 3A N3  TRUE FALSE  TRUE  TRUE  TRUE
      #4 1B N4 FALSE FALSE FALSE FALSE  TRUE
      #5 2B N5  TRUE FALSE  TRUE  TRUE  TRUE
      #6 3B N6 FALSE FALSE FALSE  TRUE FALSE
      

      【讨论】:

        【解决方案5】:

        我认为这会非常简单,但事实证明 melt 在重复列名时效果不佳,所以这有点挑剔:

        library(data.table)
        library(reshape2)
        df.names <- names(mydf)
        var.names <- paste0("V", 1:(length(df.names) - 2))
        real.names <- df.names[-(1:2)]
        names(mydf) <- c(df.names[1:2], var.names)
        dt <- data.table(melt(mydf, id.vars=c("ID", "A")))
        dt[, variable:=real.names[match(variable, var.names)]]
        dcast(
          dt[, list(value=any(value)), by=list(ID, A, variable)], 
          ID + A ~ variable
        )
        #   ID  A    AA    BB    CC    DD    EE
        # 1 1A N1  TRUE  TRUE  TRUE  TRUE FALSE
        # 2 1B N4 FALSE FALSE FALSE FALSE  TRUE
        # 3 2A N2  TRUE  TRUE FALSE FALSE FALSE
        # 4 2B N5  TRUE FALSE  TRUE  TRUE  TRUE
        # 5 3A N3  TRUE FALSE  TRUE  TRUE  TRUE
        # 6 3B N6 FALSE FALSE FALSE  TRUE FALSE    
        

        注意结果集的顺序与您的不完全相同,但如果重要的话,应该很容易重新排序。请注意,我认为 N4 在您想要的输出中是错误的。

        【讨论】:

        • 是的,你是对的 N4 得到了错误的预期结果。我已经在问题中对其进行了编辑。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-16
        • 2012-03-13
        • 1970-01-01
        • 2022-06-15
        • 2019-06-25
        • 2022-07-25
        相关资源
        最近更新 更多