【问题标题】:Divide rows into groups given the similarity between them考虑到它们之间的相似性,将行分组
【发布时间】:2020-12-14 15:27:17
【问题描述】:

鉴于此示例数据框:

DF <- data.frame(x = c(1, 0.85, 0.9, 0, 0, 0.9, 0.95),
             y = c(0, 0, 0.1, 0.9, 1, 0.9, 0.97), 
             z = c(0, 0, 0, 0.9, 0.9, 0.0, 0.9 ))

我试图根据它们的相似性将每一行分配给一个包含彼此相邻的行的组。我想使用 0.35 的截止值,这意味着可以将连续行的值 c(1, 0.85, 0.7) 分配给一个组,但 c(0, 1, 0) 不能。 关于列,列到列的差异并不重要,即 c(1, 1, 1) 和 c(0, 0, 0) 仍然可以分配给一个组,但是,如果一列中的行符合标准 (例如 c(1, 1, 1)) 但另一列中的行没有(例如 c(1, 0, 1)) - 该行无效。

这是我上面给出的示例所需的输出:

[1]  1  1  1  2  2 NA NA

我目前正在应用 abs(diff()) 函数来确定值之间的差异,然后对于每一行我取最大值(在开头添加 1 以说明第一行):

diff <- apply(DF, MARGIN = 2, function (x) abs(diff(x)))
max_diff <- c(1, apply(diff, MARGIN = 1, function (x) max(x, na.rm = T)))

max_diff
[1] 1.00 0.15 0.10 0.90 0.10 0.90 0.90

我被困在这一点上,不太确定进行小组作业的最佳方式是什么。我最初试图将 max_diff 转换为逻辑向量(max diff

  1. 我的数据集有数百万行,因此 forloop 需要很长时间,
  2. 我“忽略”组的第一个组件 - 例如我不会将第一行视为第一组的成员,因为 1 的 max_diff 值给出了 FALSE。我不想忽略任何事情。

我将非常感谢任何有关如何以有效方式进行的建议。

PS。确定站点之间差异的方法并不重要 - 这里只是 0.35 的差异,但这非常灵活。我所追求的只是一种可调整的查找相似行的方法。

【问题讨论】:

    标签: r dataframe data.table


    【解决方案1】:

    您可以进行聚类分析并使用不同的截止值h

    cl <- hclust(dist(DF))
    DF$group <- cutree(cl, h=.5)
    
    DF
    #      x    y   z group
    # 1 1.00 0.00 0.0     1
    # 2 0.85 0.00 0.0     1
    # 3 0.90 0.10 0.0     1
    # 4 0.00 0.90 0.9     2
    # 5 0.00 1.00 0.9     2
    # 6 0.90 0.90 0.0     3
    # 7 0.95 0.97 0.9     4
    

    树状图有助于确定h

    plot(cl)
    abline(h=.5, col=2)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多