首页 > 解决方案 > 交换数据帧中的单元格以最小化对相关差异总和的影响

问题描述

假设下面有一个数据框:

set.seed(100)
toydata <- data.frame(x = sample(1:50,50,replace = T),
                      y = sample(1:50,50,replace = T),
                      z = sample(1:50,50,replace = T)
                      )

然后我找到所有值低于 10 的单元格。对于第一列:

toydata[toydata$x<10,1]

我明白了

[1] 3 9 9 7

对于第二列,

toydata[toydata$y<10,2]

我明白了,我明白了

[1] 7 5 2 7 2

对于第三列,

toydata[toydata$z<10,3]

我明白了

[1] 3 1 5 2 2 6 1 3 5 8 7 3 1

以及他们的立场

which(toydata$x<10)
[1]  4 10 26 40
which(toydata$y<10)
[1]  7 30 35 48 49
which(toydata$z<10)
[1]  3  9 13 16 26 30 36 38 42 43 45 48 49

我想在值小于 10 的单元格之间交换值。值等于或大于 10 的其他单元格中的值保持不变。

条件是每个值小于 10 的单元格必须替换为新值。

目标是最小化交换前后相关性差异的总和,即最小化 |cor(x,y)-cor(x',y')|+|cor(x,z)-cor(x' ,z')|+|cor(y,z)-cor(y',z')|。

x', y', z' 是已交换的新列。

|| 表示绝对值。

有没有什么好的建议可以用任何包在 R 或 Python 中实现这一点?

谢谢。

标签: pythonr

解决方案


如果您只想交换低于某个阈值的值,即这些值的排列,那么sample您就是朋友。

swapFun <- function(x, n = 10){
  inx <- which(x < n)
  x[sample(inx)] <- x[inx]
  x
}

toydata[toydata$x < 10, 1]
#[1] 3 9 9 7
which(toydata$x < 10)
#[1]  4 10 26 40

toy <- toydata    # Work with a copy
toy[] <- lapply(toydata, swapFun)

toy[toy$x < 10, 1]
#[1] 9 7 3 9
which(toy$x < 10)
#[1]  4 10 26 40

请注意,小于的值的顺序10已更改,但没有更改它们的位置。

如果你想要另一个阈值,比如说25,就做

toydata[] <- lapply(toydata, swapFun, n = 25)

要在列之间交换,请使用另一个函数。它首先将输入data.frame转换为向量。交换以相同的方式完成。然后回到data.frame.

swapFun2 <- function(DF, n = 10){
  x <- unlist(DF)
  inx <- which(x < n)
  x[sample(inx)] <- x[inx]
  x <- as.data.frame(matrix(x, ncol = ncol(DF)))
  names(x) <- names(DF)
  x
}

toy2 <- swapFun2(toydata)

推荐阅读