【问题标题】:How to calculate the difference between different data frames with common column names如何计算具有共同列名的不同数据框之间的差异
【发布时间】:2013-01-01 17:49:51
【问题描述】:

我有三个数据帧,并试图计算两个数据帧(Df2 和 Df3)之间的差异,这些数据帧以数据帧 1 为条件。如下面的示例中所解释的,我有三个数据帧,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

【问题讨论】:

  • @Arun 是的,这是真的,这些是我数据中的情况。我试图弄清楚过去整整一周,但我无法弄清楚。你指出正确。我在想如果大于 1 列可以使用“总和”。
  • 看起来你想要大于Standard的第一个。

标签: r


【解决方案1】:

如果找到超过 1 个值并且没有找到任何值,则该脚本将获取 first biggest 值的索引。

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

感谢您的聊天。这就是你所需要的。

【讨论】:

  • 问你一个更愚蠢的问题,我将这些数据框放在不同的文件夹中,因为每个文件代表不同的物种。每个物种都有三个不同的文件,代表三种不同的实验条件。现在,如果我可以循环使用它,如何为这三个单独的文件夹设置工作目录,或者有更好的方法来做到这一点。
  • 是的,感谢您的帮助,我想把它作为一个单独的问题,因为像我这样的人可能会对此感到疑惑。
  • 我使用了您提供的代码,但该代码似乎无法正常工作。似乎中间列“dss”未包含在计算中...您能帮忙吗
  • 第六行的答案应该是-4,但是当我执行它时它给了我-1,我重复分析并发现如果我更改'dss'的值,这些值没有效果。似乎代码要么采用“das”或“tri”或两者兼而有之,但没有采用“dss”……对我来说,这真的很令人困惑。
  • 我好像没问对问题,如果高出不止一个值,我想把差值全部加到最后。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2019-09-20
    • 1970-01-01
    • 1970-01-01
    • 2020-03-25
    • 2018-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多