首先定义一些函数来按行和列方式绑定列表
# 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列中,选择从289到302的天数(使用dat1
),找到最长的连续出现1。
重复它,这次选择从dat
的303(302 + 1)到343的天数,找到最长的连续出现1。
重复343到353:选择从344(343 + 1)到353的日期,找到最长的连续出现1。
2)对所有列执行此操作
如果我想做1的总和,我可以这样做:
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
功能。我真的很想保留上面的代码
我的其他代码是相同的模式和输出格式适合我的需要,所以如果有人可以建议如何解决它我会很感激。
答案 0 :(得分:1)
OP的代码对我有用。因此,如果没有特定的错误消息,就无法理解为什么代码不为OP工作。
然而,由OP创建的样本数据集是矩阵(在它们被强制转换为purrr
之前)并且我感到很难找到一种方法来解决基本R中的任务而不使用val
:< / p>
要查找向量x
中特定值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
和子集{{1}}。