【问题标题】:List of (nearly) equal columns from a data.frame by condition in R在 R 中按条件列出来自 data.frame 的(几乎)相等的列
【发布时间】:2011-10-28 06:40:51
【问题描述】:

先不详

我有data.frames 这样的人:

  val1 val2 val3 val4 val5
1  1.1    2  1.1  2.1  4.2
2  5.7    5  5.6  4.9  9.9
3  3.1    3  3.2  2.9  5.9
4  9.6    1  9.5  1.0  2.0

并希望获得(几乎)相等的行。期望的结果类似于

[1] "val1" "val2" "val5"

因为列val3 几乎等于val1val4 几乎等于val2val5 是不同的。

详情:

  • “几乎”相等是什么意思(只是下面列出的选项之一):
    • 值的绝对差值小于一个固定数字(以上示例为 0.2)
    • 值的相对差异小于固定数字(样本约为 11%)
    • 其他有意义的指标 ;-)
  • 线性相关列的列表会更好(但我认为这更复杂)(这意味着val5 也是由val2val4 组成的组的一部分,因为它大致价值的两倍)
  • 它不必非常快,O(n^2) 就可以了。 (我的框架只有大约 12 行和 300 列)
  • 如果这不可能,那么完全相等的列的列表也可以以某种方式工作。然后我会在之前应用round() 函数

【问题讨论】:

  • 你会接受使用数组的解决方案吗?无论如何,您的数据看起来像数组数据,因为所有列都具有相同的类。
  • 当然,我会接受任何有帮助的 :-)

标签: r filter dataframe subset


【解决方案1】:

复制您的数据:

structure(list(val1 = c(1.1, 5.7, 3.1, 9.6), val2 = c(2L, 5L, 
3L, 1L), val3 = c(1.1, 5.6, 3.2, 9.5), val4 = c(2.1, 4.9, 2.9, 
1), val5 = c(4.2, 9.9, 5.9, 2)), .Names = c("val1", "val2", "val3", 
"val4", "val5"), class = "data.frame", row.names = c("1", "2", 
"3", "4"))
x
  val1 val2 val3 val4 val5
1  1.1    2  1.1  2.1  4.2
2  5.7    5  5.6  4.9  9.9
3  3.1    3  3.2  2.9  5.9
4  9.6    1  9.5  1.0  2.0

创建一个函数。该机制是围绕基本 R 函数 duplicated 进行包装,该函数具有一个用于处理列的数组的方法,这与只处理行的 data.frames 的方法不同。另外,我按照您的说法对每一列进行四舍五入,但您可以指定位数作为参数。

not_duplicated <- function(x, round_digits, margin=2){
  x2 <- apply(x, margin, round, round_digits)  
  colnames(x)[!duplicated(x2, MARGIN=margin)]
}

结果与您指定的一样:

x <- as.matrix(x)
not_duplicated(x, 0)
[1] "val1" "val2" "val5"

【讨论】:

    【解决方案2】:

    如何选择哪些行是相等的还不是很明确;例如,您可以有三列,其中 A 和 B “相等”,B 和 C “相等”,但 A 和 C 不相等。那该怎么办?解决这个问题的一种方法可能是使用层次聚类,可能是这样的:

    使用Andrie答案中的数据,先转置,做成矩阵;我还将标准化每一行(什么是一列)作为寻找线性组合的开始;这将对彼此精确倍数的行进行分组,但不是更复杂的组合。

    d <- t(as.matrix(d))
    s <- rowSums(d)
    ds <- sweep(d, 1, s, `/`)
    

    我们现在制作一棵树,为了感兴趣,绘制它。这使用默认的距离函数(欧几里得),但其他的也是可能的。

    tree <- hclust(dist(ds))
    plot(tree)
    

    然后我们选择将树分成组的位置(在这里您可以选择两个必须有多接近才能“相等”);我将它与值的总和一起输出,以查看是否是另一个的倍数。

    > grp <- cutree(tree, h=0.1)
    > cbind(grp, s)
    
         grp    s
    val1   1 19.5
    val2   2 11.0
    val3   1 19.4
    val4   2 10.9
    val5   2 22.0
    

    【讨论】:

    • 不错的答案。我考虑过聚类和因子分析,但必须小心正确地指定标准化(即scale)。否则具有固定偏移差的列将落入同一个簇中。
    • 关于明确定义:您说的很对,定义不明确。由于这只是一个预处理,我更喜欢构建更多组而不是对不相关的值进行分组。
    • 是的,更复杂的答案可能不得不担心偏移量在什么时候应该无关紧要,但我认为这个问题不会;欧几里得距离计算应该做正确的事情。
    猜你喜欢
    • 1970-01-01
    • 2019-04-07
    • 1970-01-01
    • 2019-02-16
    • 2016-10-05
    • 2019-07-16
    • 2023-04-10
    • 1970-01-01
    • 2017-01-08
    相关资源
    最近更新 更多