识别R中的运行,允许间隙

时间:2018-03-25 15:53:16

标签: r run-length-encoding

我已经在这里使用了帮助板来识别R中的运行。例如:

temp.data = rle(c(NA, NA, 1, NA, NA, 1, NA, 1, 1, 1, NA, NA, NA))
output = temp.data$lengths[temp.data$value==1] 

此处,'输出'返回以下内容:

NA NA  1 NA NA  1 NA  3 NA NA NA

这是有效的,告诉我有1,1和3的运行。但是,除了我上面所做的,我还想确定一定程度的"宽恕和"宽恕& #34 ;.例如,如果1代表发生的事件,并且NA表示事件没有发生,我想允许一个间隙。因此,我希望我的输出读取:

NA NA 1 NA NA 5 NA NA NA

或者,它可以简单地返回有1和5的运行。我试图在具有多个列和数百行的数据框中执行此操作,每个单元格是1' s和NA& #39; s,因此我想自动化这个过程。谢谢!

2 个答案:

答案 0 :(得分:4)

创建NA的游程长度,用NA替换长度为1的FALSE游戏。然后替换x索引的!inverse.rle(r)值:

r <- rle(is.na(x))
r$values[r$values][r$lengths[r$values] == 1] <- FALSE
x[!inverse.rle(r)] <- 1
x
# [1] NA NA  1 NA NA  1  1  1  1  1 NA NA NA

如果您不介意使用非basezoo::na.approx及其maxgap参数是一个方便的包装器:

na.approx(x, maxgap = 1, na.rm = FALSE)
# [1] NA NA  1 NA NA  1  1  1  1  1 NA NA NA

na.approx也可以提供数据框:

d <- data.frame(x1 = c(NA, 1, NA, 1, 1, NA),
                x2 = c(1, NA, 1, NA, NA, 1))

na.approx(d, maxgap = 1, na.rm = FALSE)
#      x1 x2
# [1,] NA  1
# [2,]  1  1
# [3,]  1  1
# [4,]  1 NA
# [5,]  1 NA
# [6,] NA  1 

如果您的数据集很大,则可以使用data.table长期使用数据集。格式:

library(data.table)
setDT(d)

# convert to long format
d2 <- melt(d, measure.var = names(d))

# for each variable and run, add group number and group length
d2[ , `:=`(g = .GRP, n = .N), by = .(variable, rleid(value))]

# for each variable, replace runs of `NA` of length 1 with 1
# leave leading and trailing NA (exclude first and last group)
d2[ , value := replace(value, is.na(value) & n == 1 &
                         g != min(g) & g != max(g), 1),
    by = .(variable)][ 
      , `:=`(g = NULL, n = NULL)] # clean-up
d2
#     variable value
#  1:       x1    NA
#  2:       x1     1
#  3:       x1     1
#  4:       x1     1
#  5:       x1     1
#  6:       x1    NA
#  7:       x2     1
#  8:       x2     1
#  9:       x2     1
# 10:       x2    NA
# 11:       x2    NA
# 12:       x2     1

答案 1 :(得分:2)

这是基础R中的一种方法。基本思想是首先将NA替换为0(以便rle的输出更具信息性),然后调整此输出和重建它,以便隔离 0已被1替换。最后,rle()结果可以按您的要求运行:

> x <- c(NA, NA, 1, NA, NA, 1, NA, 1, 1, 1, NA, NA, NA)
> x[is.na(x)] <- 0
> temp.data = rle(x)
> temp.data$values[temp.data$values == 0 & temp.data$lengths == 1] <- 1
> y <- inverse.rle(temp.data)
> rle(y)
Run Length Encoding
  lengths: int [1:5] 2 1 2 5 3
  values : num [1:5] 0 1 0 1 0