帮助使用rle命令
我在使用rle命令时遇到了一些问题,该命令用于查找参与者连续到达8个相邻点的点 例如,如果:帮助使用rle命令,r,R,我在使用rle命令时遇到了一些问题,该命令用于查找参与者连续到达8个相邻点的点 例如,如果: x <- c(0,1,0,1,1,1,1,1,1,1,1,1) 我已经成功地使用了这段代码来处理我的数据。但是,我注意到它在处理我的一个数据文件时出错了 例如,如果 x <- c(1,1,1,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1) x您需要将第一
x <- c(0,1,0,1,1,1,1,1,1,1,1,1)
我已经成功地使用了这段代码来处理我的数据。但是,我注意到它在处理我的一个数据文件时出错了
例如,如果
x <- c(1,1,1,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)
x您需要将第一行代码全部粘贴到第二行:
sum(rle(x)$lengths[ 1:(min(which( rle(x2)$values==1 & rle(x2)$lengths >= 8))-1) ]) + 8
[1] 39
但是,这里有另一种方法,使用函数filter
。这在我认为更可读的代码中产生了同样的结果:
which(filter(x2, rep(1/8, 8), sides=1) == 1)[1]
[1] 39
以这种方式使用时,filter
函数基本上计算向量中8个值块的移动平均值。然后我返回移动平均值等于1的第一个值的位置。在我教的基本编程课程中,我建议学生给子结果命名,并检查这些子结果:
lengthOfrepeatsOfAnything<-rle(x)$lengths
#4 2 5 11 2 2 3 2 17
whichRepeatsAreOfOnes<-rle(x)$values==1
#1 3 5 7 9
repeatsOfOnesLength<-lengthOfrepeatsOfAnything * whichRepeatsAreOfOnes #TRUE = 1, FALSE=0
#4 0 5 0 2 0 3 0 17
whichRepeatOfOneAreLongerThanEight<-which(repeatsOfOnesLength >= 8)
#9
result<-NA
if(length(whichRepeatOfOneAreLongerThanEight)>0){
firstRepeatOfOneAreLongerThanEight<-whichRepeatOfOneAreLongerThanEight[1]
#9
if(firstRepeatOfOneAreLongerThanEight==1){
result<-8
}
else{
repeatsBeforeFirstEightOnes<-1:(firstRepeatOfOneAreLongerThanEight-1)
#1 2 3 4 5 6 7 8
lengthsOfRepeatsBeforeFirstEightOnes<-lengthOfrepeatsOfAnything[repeatsBeforeFirstEightOnes]
#4 2 5 11 2 2 3 2
result<-sum(lengthsOfRepeatsBeforeFirstEightOnes) + 8
}
}
lengthofreepeatsofany我的建议是将代码分解成更简单的部分。正如@Nick所建议的,您希望编写易于调试的代码,模块化编码允许您这样做
# find runs of 0s and 1s
run_01 = rle(x)
# find run of 1's with length >=8
run_1 = with(run_01, which(values == 1 & lengths >=8))
# find starting position of run_1
start_pos = sum(run_01$lengths[1:(run_1 - 1)])
# add 8 to it
end_pos = start_pos + 8
如果你不习惯CamelCase,阅读起来很枯燥,但对于可重复的研究来说却非常优秀+1这是一个很好的答案,但对于同样使用dplyr
的任何用户,您都必须调用stats::filter
,以免与dplyr::filter
# find runs of 0s and 1s
run_01 = rle(x)
# find run of 1's with length >=8
run_1 = with(run_01, which(values == 1 & lengths >=8))
# find starting position of run_1
start_pos = sum(run_01$lengths[1:(run_1 - 1)])
# add 8 to it
end_pos = start_pos + 8