【问题标题】:R - how to identify consecutive rows satisfying a condition in a data frame?R - 如何识别满足数据框中条件的连续行?
【发布时间】:2015-07-16 08:46:08
【问题描述】:

我有一个位置向量(感兴趣的人可以使用基因组中的碱基对),我正在尝试识别该向量中低于给定距离阈值的位置簇。

所以使用一个简单的例子,我想识别这个向量中值之间的距离小于 20 的位置

bp = c(1, 20, 30, 100, 400, 410, 430, 500, 590, 690)

到目前为止,我已经这样做了:

d <- 20
sapply(1:length(bp), function(z){ 
  (bp[z + 1] - bp[z]) <= d
})

其中 d 是距离阈值。这给了我一个像这样的逻辑向量:

 [1]  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE    NA

我想要将“TRUE”的这些连续值标识为集群,并分别命名所有其他位置。基本上我想以如下 data.frame 结尾:

    bp cluster
1    1       a
2   20       a
3   30       a
4  100       b
5  400       c
6  410       c
7  430       c
8  500       d
9  590       e
10 690       f

非常感谢您的任何建议。

【问题讨论】:

  • 使用diff(bp) 可以获得到下一个元素的距离,如果它低于或高于你的阈值,你可以测试它。 diff(bp) &lt; 20
  • 啊!我不知道这个功能存在。非常有用。
  • 前3个值不应该是a吗?
  • 哎呀,你是对的。编辑了我的示例。
  • @CathG DavidArenburg 是正确的 - 我正在寻找连续的集群,所以虽然 30 是 > 20 from, 1,但它是

标签: r


【解决方案1】:

这是一个矢量化尝试,但如果组太多,您可能会出现字母不足,因此您可能只使用数值代替(删除 letters 部分)

data.frame(bp, cluster = letters[cumsum(c(1L, diff(bp) > 20L))])
#     bp cluster
# 1    1       a
# 2   20       a
# 3   30       a
# 4  100       b
# 5  400       c
# 6  410       c
# 7  430       c
# 8  500       d
# 9  590       e
# 10 690       f

【讨论】:

    【解决方案2】:

    一种可怜的人的方法是一个for循环......

    a <- diff(bp) < 20
    b <- 1
    d <- c()
    for(l in a) {
      if(l) {
        d <- c(d, b)
      } else{
        b <- b + 1
        d <- c(d, b)
      }
    }
    

    【讨论】:

      【解决方案3】:

      使用数字组而不是 a-h 组。但是,您可以将其转换为这种方式。

          bp = c(1, 20, 30, 100, 400, 410, 430, 500, 590, 690)
          f <- sapply(1:length(bp), function(z){ as.integer((bp[z] + d - 1) / d) })
          data.frame(bp,cluster = f)
      

      【讨论】:

      • 感谢您的努力,但这不能正常工作。 as.integer 只对第一个集群进行分组...
      猜你喜欢
      • 2021-10-20
      • 2019-07-29
      • 1970-01-01
      • 2022-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多