【问题标题】:Grouping data that follows sequence N+1 in R在 R 中对遵循序列 N+1 的数据进行分组
【发布时间】:2020-06-08 14:48:20
【问题描述】:

所以我有一个包含三列的数据集:位置、时间和强度。强度充满了二进制值,我已过滤为仅包含 1(因为这表示感兴趣的对象,而 0 是背景)。

我需要一种能够将数据分组为 N+1 之后的序列的方法;参考下图。

Snapshot of my data

如您所见,第一列从 4 到 22,以 1 为增量,然后跳到 39,我的数据集中有很多这样的情况(每个跳过代表一个对象的结束和另一个对象的开始)存在一种查找序列 N+1 之后的数字位置的方法,然后将其分组到一个变量中,从而使我能够识别每个对象的位置。

编辑//

在回复之后我使用了代码并生成了这个,它生成了另一列(称为 T2),其中包含数字:

structure(list(pixel_pos = c(4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 
12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 21L, 22L, 39L), 
    Time_point = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 1, 1), Intensity = c(1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), T2 = c(1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    2L)), row.names = c(NA, -20L), class = c("tbl_df", "tbl", 
"data.frame")) 

有没有办法将 T2 中 1、2、3 等之后的所有数字分组,因为这些数字代表对象。再次感谢!

//编辑 2 原始表,没有过滤(存在 0)

Pixel_pos = 1:40, 
Time_point = c(1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), 
Intensity = c(0, 0, 
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1)), 
row.names = c(NA, 40L), class = c("tbl_df", "tbl", "data.frame"))

【问题讨论】:

  • 我不知道您所说的“将 T2 中 1、2、3 等之后的所有数字分组,因为它们代表对象。”我以为T2 是你想要的。如果不是这样,您能否展示一下您想要什么?
  • 对不起,我应该更清楚,所以到目前为止,我的数据已使用 filter(variable, Intensity == 1) 过滤,因此不存在 0 强度值。我希望有一种方法可以确保在 T2 中分配给每个像素位置的变量即使在强度值 0 返回表后仍然存在,以便绘制图表。如果我尝试在存在强度为 0 的像素时应用您建议的功能,我认为它不会起作用。所以我想知道是否有办法保存分配,然后将其与完整的表合并。谢谢
  • 如果没有看到intensity = 0 的任何数据,这真的很难回答。
  • 我附上了另一个编辑,非常感谢您提供的任何帮助。干杯

标签: r


【解决方案1】:

方法很多,这里有两种(调用你的数据df):

df$group = as.integer(factor(df$first_column - 1:nrow(df)))

df$group = cumsum(c(1, diff(df$first_column) > 1))

如果您遇到这些问题或需要更多帮助,请以可重现的方式分享您的一些数据 - 数据图片很难处理。例如,dput(df[1:20, ]) 提供了数据框前 ​​20 行的可复制粘贴版本。

【讨论】:

  • 感谢您的快速回复,我已在帖子中添加了编辑
【解决方案2】:

我不确定我是否理解你的问题,如果没有可重复的例子,真的很难提供帮助

无论如何,我会提供一个 data.table 解决方案:

虚拟数据

set.seed(1)
dt <- data.table(x = 1:100, y = sample(0:1, 100, TRUE, prob = c(.3, .6)))

那么我们:

dt[, id := rleid(y)][, startPos := ifelse(id != shift(id, 1), 1, 0)][y == 1 & startPos == 1, ]

里面有什么:

  • id := rleid(y):我们创建一个新变量id,它具有变量 y 的运行长度 id,即它的连续运行,非常接近你想要的。
  • startPos := ifelse(id != shift(id, 1), 1, 0):我们创建一个新变量 startPos,如果 id 与下一个不同(因此标记了此类 id 的起始位置),该变量将具有 1。
  • 最后,我们过滤具有y == 1(您感兴趣的数据)和startPos == 1(起始位置)的结果。 dt 仍然拥有所有原始数据。

希望对你有帮助

【讨论】:

    【解决方案3】:

    如果您对dplyr 没问题,我们可以使用lag 函数简化很多。这特别有用,因为我们可以为第一行设置一个默认值。

    library(dplry)
    data %>% 
      mutate(T2 = cumsum(pixel_pos - lag(pixel_pos, default = 0) > 1))
    # A tibble: 20 x 4
       pixel_pos Time_point Intensity    T2
           <int>      <dbl>     <dbl> <int>
     1         4          1         1     1
     2         5          1         1     1
     3         6          1         1     1
    ...
    18        21          1         1     1
    19        22          1         1     1
    20        39          1         1     2
    

    【讨论】:

      【解决方案4】:

      我设法让一切正常使用

      df$group = as.integer(因子(df$first_column - 1:nrow(df)))

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-27
        • 1970-01-01
        相关资源
        最近更新 更多