【问题标题】:Making subsets of recurring data from a large data set从大型数据集中制作重复数据的子集
【发布时间】:2019-04-16 02:42:34
【问题描述】:

我正在尝试使用 R 从大型数据集中提取某些数据。这些数据来自一个经历了多个阶段的过程,比如说阶段 0 到 5。我有一个包含多个运行过程的数据集。

我正在尝试提取每次运行的数据。我想创建第一次出现阶段 0 到 5 的子集,然后创建另一个子集,再次出现阶段 0 到 5(第二次运行)。数据集仅包含按时间顺序排列的过程数据和阶段编号,它不知道它在哪个运行中。但是,阶段是按顺序排列的,因此阶段列从 0 到 5,然后又从 0 开始。

我已经尝试使用一些 while 和 for 循环来组织数据,但是在如此大的数据集(700 000 个条目)上这非常慢。即使使用只有 10000 个左右条目的一小部分也需要很长时间。

数据集可能看起来像这样(第二列是相位):

01, 0, 2, 4, 5, 3, 4,
02, 0, 3, 4, 5, 2, 2,
03, 0, 4, 5, 4, 9, 8,
04, 1, 8, 9, 2, 7, 3,
05, 1, 8, 7, 0, 7, 8,
06, 2, 8, 4, 9, 7, 8,
07, 2, 9, 7, 5, 0, 8,
08, 2, 8, 6, 5, 7, 9,
07, 2, 8, 7, 6, 7, 9,
08, 3, 7, 8, 6, 7, 9,
09, 3, 7, 9, 8, 7, 8, 
10, 4, 5, 6, 7, 4, 3,
11, 4, 6, 7, 5, 6, 4,
12, 5, 6, 4, 3, 2, 2,
13, 0, 6, 3, 3, 2, 5,
14, 0, 5, 6, 3, 2, 2,
15, 1, 5, 2, 1, 4, 4,

请注意,每相的线数不是恒定的。

我希望从上面的例子中得到的子集是:

01, 0, 2, 4, 5, 3, 4,
02, 0, 3, 4, 5, 2, 2,
03, 0, 4, 5, 4, 9, 8,
04, 1, 8, 9, 2, 7, 3,
05, 1, 8, 7, 0, 7, 8,
06, 2, 8, 4, 9, 7, 8,
07, 2, 9, 7, 5, 0, 8,
08, 2, 8, 6, 5, 7, 9,
07, 2, 8, 7, 6, 7, 9,
08, 3, 7, 8, 6, 7, 9,
09, 3, 7, 9, 8, 7, 8, 
10, 4, 5, 6, 7, 4, 3,
11, 4, 6, 7, 5, 6, 4,
12, 5, 6, 4, 3, 2, 2,

13, 0, 6, 3, 3, 2, 5,
14, 0, 5, 6, 3, 2, 2,
15, 1, 5, 2, 1, 4, 4,

(注意:在原始数据集中,阶段总是在 5 结束)

【问题讨论】:

    标签: r subset


    【解决方案1】:

    在您的问题中,仅当阶段索引(在第二列中给出)减少时才开始新的子集。因此,我们可以将whichdiff 结合起来,以获得一个阶段结束的行索引。

    我们首先可以获得子集开始/结束的行索引,如下所示:

    end   <- which(diff(data[,2]) < 0)
    start <- c(1, end + 1)
    end   <- c(end, nrow(data))
    

    然后我们可以使用它来制作一个包含子集的列表,如下所示:

    subsets <- vector("list", length(start))
    
    for (idx in 1:length(start))
      subsets[[idx]] <- data[start[idx]:end[idx],]
    

    请注意,最后一步仍然使用 for 循环。我希望split 可以实现类似的效果,但我没有成功尝试。

    编辑:当然,R 有一个避免 for 语句的解决方案。我们应该创建一个新向量,为每一行指示它属于哪个子集。鉴于上述两个向量endstart,这很容易实现(参见下面的代码 sn-p)。然后我们可以使用内置函数split 并将其输出转换为矩阵列表(灵感来自this answer)。

    # How many rows does each subset has?
    n <- end - start + 1
    
    # Create vector that indicates for each row to which subset it belongs 
    idx_subset <- rep(1:length(start), n)
    
    # Create the subsets
    subsets <- lapply( split(data, idx_subset), matrix, ncol=7)
    

    【讨论】:

    • 非常感谢您的回答。 @nsignhs 的回答正是我需要的。但还是感谢你的努力!非常感谢。
    【解决方案2】:

    这是一个矢量化的解决方案

    # sample df
    df = read.table(text = "
    v1  phase   v3  v4  v5  v6  v7
    01  0   2   4   5   3   4
    02  0   3   4   5   2   2
    03  0   4   5   4   9   8
    04  1   8   9   2   7   3
    05  1   8   7   0   7   8
    06  2   8   4   9   7   8
    07  2   9   7   5   0   8
    08  2   8   6   5   7   9
    07  2   8   7   6   7   9
    08  3   7   8   6   7   9
    09  3   7   9   8   7   8   
    10  4   5   6   7   4   3
    11  4   6   7   5   6   4
    12  5   6   4   3   2   2
    13  0   6   3   3   2   5
    14  0   5   6   3   2   2
    15  1   5   2   1   4   4
                    ", stringsAsFactors = F, header = T)
    
    # create groups for splitting df
    grp <- cumsum( c( 0, diff( df$phase ) ) < 0 ) + 1
    
    # split the df
    split(df, grp)
    #> $`1`
    #>    v1 phase v3 v4 v5 v6 v7
    #> 1   1     0  2  4  5  3  4
    #> 2   2     0  3  4  5  2  2
    #> 3   3     0  4  5  4  9  8
    #> 4   4     1  8  9  2  7  3
    #> 5   5     1  8  7  0  7  8
    #> 6   6     2  8  4  9  7  8
    #> 7   7     2  9  7  5  0  8
    #> 8   8     2  8  6  5  7  9
    #> 9   7     2  8  7  6  7  9
    #> 10  8     3  7  8  6  7  9
    #> 11  9     3  7  9  8  7  8
    #> 12 10     4  5  6  7  4  3
    #> 13 11     4  6  7  5  6  4
    #> 14 12     5  6  4  3  2  2
    #> 
    #> $`2`
    #>    v1 phase v3 v4 v5 v6 v7
    #> 15 13     0  6  3  3  2  5
    #> 16 14     0  5  6  3  2  2
    #> 17 15     1  5  2  1  4  4
    

    reprex package (v0.2.1) 于 2019 年 4 月 15 日创建

    解释:diff 计算特定值与其前一个值的差,然后&lt; 运算符评估结果是否小于0。生成的T, F 逻辑向量在前面附加了另一个0,以保持向量长度与df 中的行数相同。 cumsum 然后找到值的累积运行总和,仅当阶段 5 之后的阶段值较小时才会改变,因此本质上是创建组。然后这些组(grp)用于拆分df

    【讨论】:

    • 这成功了!非常感谢。我使用“newData
    • 是的,就是这样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-20
    • 1970-01-01
    • 2020-03-31
    • 1970-01-01
    • 2011-04-18
    相关资源
    最近更新 更多