【问题标题】:R: Sum columns based on match table, merging column namesR:基于匹配表求和列,合并列名
【发布时间】:2017-03-30 18:42:12
【问题描述】:

我有一个这样的数据框(其中字母是列名):

a   b   c   B   C   A
1   2   3   6   7   8
1   2   3   6   7   8
1   2   3   6   7   8
1   2   3   6   7   8

我想根据这个匹配表对列求和:

a   A
b   B
c   C

同时也合并列名,结果是:

a/A b/B c/C
9   8   10
9   8   10
9   8   10
9   8   10

请记住,该解决方案需要适用于大型数据框,因此我不能手动指定新的列名。

非常感谢!

【问题讨论】:

    标签: r


    【解决方案1】:

    你可以这样做:

    res <- apply(df.match, 1, function(x) rowSums(df[,c(x[1], x[2])]))
    colnames(res) <- paste0(df.match[,1], "/", df.match[,2])
    
    #     a/A    b/B   c/C
    #[1,]    9    8   10
    #[2,]    9    8   10
    #[3,]    9    8   10
    #[4,]    9    8   10
    #[5,]    9    8   10
    

    df 是您的数据框,df.match 是您匹配的列名。

    【讨论】:

    • 可行,但最终的行名必须考虑到我的示例中的原始行名
    • 太棒了!选择这个作为答案是因为它在我看来是最简洁的。
    【解决方案2】:

    基本上涉及使用match 几次。使用@Lyngbakr 的数据。

    #DATA
    df = structure(list(a = c(1, 1, 1, 1, 1), b = c(2, 2, 2, 2, 2), c = c(3, 
    3, 3, 3, 3), A = c(8, 8, 8, 8, 8), C = c(7, 7, 7, 7, 7), B = c(6, 
    6, 6, 6, 6)), .Names = c("a", "b", "c", "A", "C", "B"), row.names = c(NA, 
    -5L), class = "data.frame")
    df.names = structure(list(First = c("a", "b", "c"), Second = c("A", "B", 
    "C")), .Names = c("First", "Second"), row.names = c(NA, -3L), class = "data.frame")
    
    toadd = which(colnames(df) %in% df.names[,1])
    addto = match(df.names[,2][match(colnames(df)[toadd], df.names[,1])], colnames(df))
    setNames(object = df[,addto] + df[,toadd], nm = paste(colnames(df)[toadd], colnames(df)[addto], sep = "/"))
    #  a/A b/B c/C
    #1   9   8  10
    #2   9   8  10
    #3   9   8  10
    #4   9   8  10
    #5   9   8  10
    

    【讨论】:

      【解决方案3】:

      这是一种方法......

      df <- data.frame(a=c(1,1,1,1),b=c(2,2,2,2),c=c(3,3,3,3),B=c(6,6,6,6),C=c(7,7,7,7),A=c(8,8,8,8))
      matchtab <- data.frame(V1=c("a","b","c"),V2=c("A","B","C"),stringsAsFactors = FALSE)
      
      df2 <- do.call(cbind,lapply(seq_len(nrow(matchtab)),function(i) 
                                 data.frame(df[,matchtab$V1[i]]+df[,matchtab$V2[i]])))
      names(df2) <- paste0(matchtab$V1,"/",matchtab$V2)
      
      df2
        a/A b/B c/C
      1   9   8  10
      2   9   8  10
      3   9   8  10
      4   9   8  10
      

      【讨论】:

        【解决方案4】:

        这样的?

        df <- data.frame(a = rep(1, 5), b = rep(2, 5), c = rep(3, 5), 
                         A = rep(8, 5), C = rep(7, 5), B = rep(6, 5))
        
        df.names <- data.frame(First = c("a", "b", "c"), Second =  c("A", "B", "C"))
        
        apply(df.names, MAR = 1, FUN = function(mynames, mydf) rowSums(df[,colnames(df) %in% mynames]), mydf = df)
        

        给予,

             [,1] [,2] [,3]
        [1,]    9    8   10
        [2,]    9    8   10
        [3,]    9    8   10
        [4,]    9    8   10
        [5,]    9    8   10
        

        【讨论】:

        • 是的,但最终的行名必须考虑到我的示例中的原始行名
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-23
        • 1970-01-01
        • 2020-10-30
        • 1970-01-01
        相关资源
        最近更新 更多