首页 文章

如何计算具有公共列名的不同数据框之间的差异

提问于
浏览
4

我有三个数据帧并试图计算由数据帧1调节的两个数据帧(Df2和Df3)之间的差异 . 如下面的例子中所解释的,我有三个数据帧,Df1,Df2和Df3具有通用名称 . 在第一步中,在Df1中,我想比较“标准”列与所有三列的值,“Das”,“Dss”和“Tri”可能是行方式,这些列的任何值,“Das”, “Dss”和“Tri”高于Df1中的“Standard”,计算Df2和Df3中相同位置的差异,并将差异放在单独的列中 .

Df1             
    Names   Standard    Das Dss Tri
    Aa  3   3   6   2
    Ab  4   6   4   3
    Ac  2   5   2   4
    Ad  4   3   3   8
    Ae  6   4   5   7
    Af  4   5   7   5
    Ag  2   6   8   2
    Ah  9   7   6   2

Df2         
    Names   Das Dss Tri
    Aa  4   2   5
    Ab  7   5   4
    Ac  5   7   2
    Ad  6   4   3
    Ae  5   3   5
    Af  3   2   6
    Ag  2   5   4
    Ah  4   6   3

DF3

Names   Das Dss Tri
    Aa  5   3   5
    Ab  8   5   4
    Ac  6   7   2
    Ad  6   4   7
    Ae  5   3   8
    Af  4   5   6
    Ag  1   5   4
    Ah  4   6   3

最终输出

Df3             
    Names   Das Dss Tri Difference
    Aa  5   3   5   -1
    Ab  8   5   4   -1
    Ac  6   7   2   -1
    Ad  6   4   7   -4
    Ae  5   3   8   -3
    Af  4   5   6   -4
    Ag  1   5   4   1
    Ah  4   6   3   0

2 回答

  • 1

    如果找到的值超过1,则获取 first biggest 值索引的脚本如果没有找到值,则返回 NA .

    df1 <- structure(list(standard = c(3, 4, 2, 4, 6, 4, 2, 9), das = c(3, 
    6, 5, 3, 4, 5, 6, 7), dss = c(6, 4, 2, 3, 5, 7, 8, 6), tri = c(2, 
    3, 4, 8, 7, 5, 2, 2)), .Names = c("standard", "das", "dss", "tri"
    ), row.names = c(NA, -8L), class = "data.frame")
    
    df2 <- structure(list(das = c(4, 7, 5, 6, 5, 3, 2, 4), dss = c(2, 
    5, 7, 4, 3, 2, 5, 6), tri = c(5,4,2,3,5,6,4,3)), .Names = c("das", "dss", "tri"
    ), row.names = c(NA, -8L), class = "data.frame")
    
    df3 <- structure(list(das = c(5, 8, 6, 6, 5, 4, 1, 4), dss = c(3, 
         5, 7, 4, 3, 5, 5, 6), tri = c(5,4,2,7,8,6,4,3)), .Names = c("das", "dss", "tri"
     ), row.names = c(NA, -8L), class = "data.frame")
    
    # get indices. run through every row of df1
    # and get the maximum column index > standard
    idx.v <- sapply( 1:nrow(df1), function(idx) {
        t <- which(df1[idx, 2:4] > df1[idx, 1])
    })
    
    df3$result <- sapply(1:length(idx.v), function(ix) {
        col.idx <- idx.v[[ix]]
        len.idx <- length(col.idx)
        if (len.idx > 0) {
            res <- sum(df2[ix, col.idx] - df3[ix, col.idx])
        } else {
            res <- NA
        }
    })
    
    Output:
    
    > df3
      das dss tri result
    1   5   3   5     -1
    2   8   5   4     -1
    3   6   7   2     -1
    4   6   4   7     -4
    5   5   3   8     -3
    6   4   5   6     -4
    7   1   5   4      1
    8   4   6   3     NA
    

    谢谢你的聊天 . 这就是你所需要的 .

  • 1

    我认为这是正确的结果,但请注意第七个值不同 . 使用三列的最大值(更简单的任务)会产生在更多插槽中不同的结果 .

    df1.w <- sapply( seq(1, nrow(df1)), 
                     function(idx) min(c(Inf, which(df1[-(1:2)][idx,] > df1[idx, 2])))
                    )
    
    df1.mat <- matrix(c(seq(1, nrow(df1)), df1.w), ncol=2)
    df1.mat[is.infinite(df1.mat)] <- 1
    
    ifelse(is.infinite(df1.w), 0, 
           df2[-1][df1.mat] - df3[-1][df1.mat]
           )
    
    ## [1] -1 -1 -1 -4 -3 -1  1  0
    

    如果您确实想在df1 [ - (1:2)]中使用最大值的索引,请将 df1.wsapply 调用)的定义替换为:

    df1.w <- apply(df1[-(1:2)], 1, which.max)
    

    使用上面的其余代码然后给出这个结果:

    ## [1] -1 -1 -1 -4 -3 -3  0  0
    

相关问题