R:查找连续出现的数字
R: find consecutive occurrence of a number
首先定义一些函数来按行和按列绑定列表
# a function to append vectors row wise
rbindlist <- function(list) {
n <- length(list)
res <- NULL
for (i in seq(n)) res <- rbind(res, list[[i]])
return(res)
}
cbindlist <- function(list) {
n <- length(list)
res <- NULL
for (i in seq(n)) res <- cbind(res, list[[i]])
return(res)
}
# generate sample data
sample.dat <- list()
set.seed(123)
for(i in 1:365){
vec1 <- sample(c(0,1), replace=TRUE, size=5)
sample.dat[[i]] <- vec1
}
dat <- rbindlist(sample.dat)
dat
有五列。每列都是一个位置,一年中有 365 天(365 行),其值为 1 或 0。
我有另一个数据框(见下文),它在 dat
.
中的每一列(位置)都有一年中的某些日子
# generate second sample data
set.seed(123)
sample.dat1 <- list()
for(i in 1:5){
vec1 <- sort(sample(c(258:365), replace=TRUE, size=4), decreasing = F)
sample.dat1[[i]] <- vec1
}
dat1 <- cbindlist(sample.dat1)
我需要使用 dat1
对 dat
中的天数进行子集计算。下面的例子:
1) 对于位置 1(dat1
和 dat
中的第一列):
在 dat
的第 1 列中,select 从 289 到 302 的天数(使用 dat1
),找到连续出现时间最长的 1。
重复它,这次 select 从 303 (302 + 1) 到 dat
的 343 天,找到连续出现时间最长的 1。
重复 343 到 353:select 从 344 (343 + 1) 到 353 的天数,找出连续出现时间最长的 1.
2) 对所有列执行此操作
如果我想求和,我可以这样做:
dat <- as.tibble(dat)
dat1 <- as.tibble(dat1)
pmap(list(dat,dat1), ~ {
range1 <- ..2[1]
range2 <- ..2[2]
range3 <- ..2[3]
range4 <- ..2[4]
sum.range1 <- sum(..1[range1:range2]) # this will generate sum between range 1 and range 2
sum.range2 <- sum(..1[range2:range3]) # this will generate sum between range 2 and range 3
sum.range3 <- sum(..1[range3:range4]) # this will generate sum between range 3 and range 4
c(sum.range1=sum.range1,sum.range2=sum.range2,sum.range3=sum.range3)
})
对于每个范围之间连续出现最长的 1,我想到了使用 rle
函数。示例如下:
pmap(list(dat,dat1), ~ {
range1 <- ..2[1]
range2 <- ..2[2]
range3 <- ..2[3]
range4 <- ..2[4]
spell.range1 <- rle(..1[range1:range2]) # sort the data, this shows the longest run of ANY type (0 OR 1)
spell.1.range1 <- tapply(spell.range1$lengths, spell.range1$values, max)[2] # this should select the maximum consequtive run of 1
spell.range2 <- rle(..1[range2:range3]) # sort the data, this shows the longest run of ANY type (0 OR 1)
spell.1.range2 <- tapply(spell.range2$lengths, spell.range2$values, max)[2] # this should select the maximum consequtive run of 1
spell.range3 <- rle(..1[range3:range4]) # sort the data, this shows the longest run of ANY type (0 OR 1)
spell.1.range3 <- tapply(spell.range3$lengths, spell.range3$values, max)[2] # this should select the maximum consequtive run of 1
c(spell.1.range1 = spell.1.range1, spell.1.range2 = spell.1.range2, spell.1.range3 = spell.1.range3)
})
我收到一个错误,我认为这是因为我没有在这里正确使用 rle
函数。我真的很想保留上面的代码,因为
我的其他代码采用相同的模式,输出格式适合我的需要,所以如果有人可以建议如何修复它,我将不胜感激。
OP 的代码对我有用。因此,如果没有特定的错误消息,就无法理解为什么代码 不 为 OP 工作。
但是,OP 创建的样本数据集是矩阵(在它们被强制转换为 tibble
之前),我觉得很难找到一种方法来解决 base R 中的任务而不使用 purrr
:
要查找向量 x
中特定值 val
的连续出现次数,我们可以使用以下函数:
max_rle <- function(x, val) {
y <- rle(x)
len <- y$lengths[y$value == val]
if (length(len) > 0) max(len) else NA
}
示例:
max_rle(c(0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1), 1)
[1] 4
max_rle(c(0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1), 0)
[1] 2
# find consecutive occurrences in column batches
lapply(seq_len(ncol(dat1)), function(col_num) {
start <- head(dat1[, col_num], -1L)
end <- tail(dat1[, col_num], -1L) - 1
sapply(seq_along(start), function(range_num) {
max_rle(dat[start[range_num]:end[range_num], col_num], 1)
})
})
[[1]]
[1] 8 4 5
[[2]]
[1] 4 5 2
[[3]]
[1] NA 3 4
[[4]]
[1] 5 5 4
[[5]]
[1] 3 2 3
第一个 lapply()
分别遍历 dat
和 dat1
的列。第二个 sapply()
循环存储在 dat1
中的行范围并相应地子集 dat
。
首先定义一些函数来按行和按列绑定列表
# a function to append vectors row wise
rbindlist <- function(list) {
n <- length(list)
res <- NULL
for (i in seq(n)) res <- rbind(res, list[[i]])
return(res)
}
cbindlist <- function(list) {
n <- length(list)
res <- NULL
for (i in seq(n)) res <- cbind(res, list[[i]])
return(res)
}
# generate sample data
sample.dat <- list()
set.seed(123)
for(i in 1:365){
vec1 <- sample(c(0,1), replace=TRUE, size=5)
sample.dat[[i]] <- vec1
}
dat <- rbindlist(sample.dat)
dat
有五列。每列都是一个位置,一年中有 365 天(365 行),其值为 1 或 0。
我有另一个数据框(见下文),它在 dat
.
# generate second sample data
set.seed(123)
sample.dat1 <- list()
for(i in 1:5){
vec1 <- sort(sample(c(258:365), replace=TRUE, size=4), decreasing = F)
sample.dat1[[i]] <- vec1
}
dat1 <- cbindlist(sample.dat1)
我需要使用 dat1
对 dat
中的天数进行子集计算。下面的例子:
1) 对于位置 1(dat1
和 dat
中的第一列):
在 dat
的第 1 列中,select 从 289 到 302 的天数(使用 dat1
),找到连续出现时间最长的 1。
重复它,这次 select 从 303 (302 + 1) 到 dat
的 343 天,找到连续出现时间最长的 1。
重复 343 到 353:select 从 344 (343 + 1) 到 353 的天数,找出连续出现时间最长的 1.
2) 对所有列执行此操作
如果我想求和,我可以这样做:
dat <- as.tibble(dat)
dat1 <- as.tibble(dat1)
pmap(list(dat,dat1), ~ {
range1 <- ..2[1]
range2 <- ..2[2]
range3 <- ..2[3]
range4 <- ..2[4]
sum.range1 <- sum(..1[range1:range2]) # this will generate sum between range 1 and range 2
sum.range2 <- sum(..1[range2:range3]) # this will generate sum between range 2 and range 3
sum.range3 <- sum(..1[range3:range4]) # this will generate sum between range 3 and range 4
c(sum.range1=sum.range1,sum.range2=sum.range2,sum.range3=sum.range3)
})
对于每个范围之间连续出现最长的 1,我想到了使用 rle
函数。示例如下:
pmap(list(dat,dat1), ~ {
range1 <- ..2[1]
range2 <- ..2[2]
range3 <- ..2[3]
range4 <- ..2[4]
spell.range1 <- rle(..1[range1:range2]) # sort the data, this shows the longest run of ANY type (0 OR 1)
spell.1.range1 <- tapply(spell.range1$lengths, spell.range1$values, max)[2] # this should select the maximum consequtive run of 1
spell.range2 <- rle(..1[range2:range3]) # sort the data, this shows the longest run of ANY type (0 OR 1)
spell.1.range2 <- tapply(spell.range2$lengths, spell.range2$values, max)[2] # this should select the maximum consequtive run of 1
spell.range3 <- rle(..1[range3:range4]) # sort the data, this shows the longest run of ANY type (0 OR 1)
spell.1.range3 <- tapply(spell.range3$lengths, spell.range3$values, max)[2] # this should select the maximum consequtive run of 1
c(spell.1.range1 = spell.1.range1, spell.1.range2 = spell.1.range2, spell.1.range3 = spell.1.range3)
})
我收到一个错误,我认为这是因为我没有在这里正确使用 rle
函数。我真的很想保留上面的代码,因为
我的其他代码采用相同的模式,输出格式适合我的需要,所以如果有人可以建议如何修复它,我将不胜感激。
OP 的代码对我有用。因此,如果没有特定的错误消息,就无法理解为什么代码 不 为 OP 工作。
但是,OP 创建的样本数据集是矩阵(在它们被强制转换为 tibble
之前),我觉得很难找到一种方法来解决 base R 中的任务而不使用 purrr
:
要查找向量 x
中特定值 val
的连续出现次数,我们可以使用以下函数:
max_rle <- function(x, val) {
y <- rle(x)
len <- y$lengths[y$value == val]
if (length(len) > 0) max(len) else NA
}
示例:
max_rle(c(0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1), 1)
[1] 4
max_rle(c(0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1), 0)
[1] 2
# find consecutive occurrences in column batches
lapply(seq_len(ncol(dat1)), function(col_num) {
start <- head(dat1[, col_num], -1L)
end <- tail(dat1[, col_num], -1L) - 1
sapply(seq_along(start), function(range_num) {
max_rle(dat[start[range_num]:end[range_num], col_num], 1)
})
})
[[1]] [1] 8 4 5 [[2]] [1] 4 5 2 [[3]] [1] NA 3 4 [[4]] [1] 5 5 4 [[5]] [1] 3 2 3
第一个 lapply()
分别遍历 dat
和 dat1
的列。第二个 sapply()
循环存储在 dat1
中的行范围并相应地子集 dat
。