【问题标题】:Identifying sequences of repeated numbers in R识别R中重复数字的序列
【发布时间】:2013-11-23 14:08:03
【问题描述】:

我有一个很长的时间序列,我需要识别和标记重复值的序列。以下是一些数据:

   DATETIME WDIR
1  40360.04   22
2  40360.08   23
3  40360.12  126
4  40360.17  126
5  40360.21  126
6  40360.25  126
7  40360.29   25
8  40360.33   26
9  40360.38  132
10 40360.42  132
11 40360.46  132
12 40360.50   30
13 40360.54  132
14 40360.58   35

因此,如果我需要记录一个值何时重复三次或更多次,我需要标记一个包含四个“126”的序列和一个包含三个“132”的序列。

我对 R 很陌生。我希望我使用 cbind 在此数组中创建一个新列,在相应的行中使用“T”,但如何正确填充该列是一个谜。请问有什么指点吗?非常感谢。

【问题讨论】:

    标签: r


    【解决方案1】:

    正如 Ramnath 所说,您可以使用 rle

    rle(dat$WDIR)
    Run Length Encoding
      lengths: int [1:9] 1 1 4 1 1 3 1 1 1
      values : int [1:9] 22 23 126 25 26 132 30 132 35
    

    rle 返回一个包含两个组件,长度和值的对象。我们可以使用长度部分来构建一个新列,用于标识哪些值重复超过 3 次。

    tmp <- rle(dat$WDIR)
    rep(tmp$lengths >= 3,times = tmp$lengths)
    [1] FALSE FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE
    

    这将是我们的新专栏。

    newCol <- rep(tmp$lengths > 1,times = tmp$lengths)
    cbind(dat,newCol)
       DATETIME WDIR newCol
    1  40360.04   22  FALSE
    2  40360.08   23  FALSE
    3  40360.12  126   TRUE
    4  40360.17  126   TRUE
    5  40360.21  126   TRUE
    6  40360.25  126   TRUE
    7  40360.29   25  FALSE
    8  40360.33   26  FALSE
    9  40360.38  132   TRUE
    10 40360.42  132   TRUE
    11 40360.46  132   TRUE
    12 40360.50   30  FALSE
    13 40360.54  132  FALSE
    14 40360.58   35  FALSE
    

    【讨论】:

      【解决方案2】:

      使用rle 完成工作!!这是一个惊人的函数,可以计算序列中数字的连续重复次数。下面是一些示例代码,说明如何使用rle 来标记数据中的不法分子。这将返回数据框中所有连续重复 3 次或更多次 WDIR 的行。

      runs = rle(mydf$WDIR)
      subset(mydf, WDIR %in% runs$values[runs$lengths >= 3])
      

      【讨论】:

        【解决方案3】:

        两种选择。

        假设数据已加载:

        dat <- read.table(textConnection("
        DATETIME WDIR
        40360.04   22
        40360.08   23
        40360.12  126
        40360.17  126
        40360.21  126
        40360.25  126
        40360.29   25
        40360.33   26
        40360.38  132
        40360.42  132
        40360.46  132
        40360.50   30
        40360.54  132
        40360.58   35"), header=T)
        

        选项 1:排序

        dat <- dat[order(dat$WDIR),] # needed for the 'repeats' to be pasted into the correct rows in next step
        dat$count <- rep(table(dat$WDIR),table(dat$WDIR))
        dat$more4 <- ifelse(dat$count < 4, F, T)
        dat <- dat[order(dat$DATETIME),] # sort back to original order
        dat
        

        选项 2:Oneliner

        dat$more4 <- ifelse(dat$WDIR %in% names(which(table(dat$WDIR)>3)),T,F)
        dat
        

        我认为作为一个新用户,选项 1 可能是一种更简单的逐步方法,尽管 rep(table(), table()) 最初可能并不直观。

        【讨论】:

          猜你喜欢
          • 2021-12-24
          • 1970-01-01
          • 1970-01-01
          • 2015-09-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-12-22
          • 2010-09-13
          相关资源
          最近更新 更多