我已经在这里使用了帮助板来识别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,因此我想自动化这个过程。谢谢!
答案 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
如果您不介意使用非base
,zoo::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