如何计算 R 中向量中相同元素的数量?
How to count the number of same elements which are in order in a vector in R?
例如,我有一个这样的矢量:
x<-c(1,1,1, -1, 1,1,1,1,1,1, -1,-1, 1,1, -1,-1,-1,-1,-1,-1,-1, 1)
我希望算法生成一个向量 (3,1,6,2,2,7,1)
表示 3 个“1”、1 个“-1”、6 个“1”等...
我开发了以下算法,但它不适用于每个向量 x,我可能会使用它。
y<-c(0)
q=0
z=0
w=0
e=1
if (x[1]==1)
{
q<-abs(sum(x[1:(min(which(x < 0))-1)]))
y[e]<-q
k=q+1
z<-abs(sum(x[k:min(which(x < 0))]))
e=e+1
y[e]<-z
k=k+z
r<-matrix(c(which(x < 0)))
w<-matrix(c(which(x > 0)))
while( k<22 )
{
if( all(r<k) )
{
z<-sum(x[k:22])
e=e+1
y[e]<-z
k=k+z
}else
{
z<-abs(sum(x[k:min(r[which(r > k)]-1)]))
e=e+1
y[e]<-z
k=k+z
}
if( all(w<k) )
{
z<-abs(sum(x[k:22]))
e=e+1
y[e]<-z
k=k+z
}else
{z<-abs(sum(x[k:min(w[which(w > k)]-1)]))
e=e+1
y[e]<-z
k=k+z
}
}}
但是对于向量
x<-c(1,1,1, -1, 1,1,1,1,1,1, -1,-1, 1,1, -1,-1,-1,-1,-1,-1,-1,-1)
它有效。
您是否有任何想法可以更快更轻松地执行此操作,或者只是在我自己的代码中找到问题?
谢谢大家!
你可以尝试函数 rle
:
rle(x)
#Run Length Encoding
# lengths: int [1:7] 3 1 6 2 2 7 1
# values : num [1:7] 1 -1 1 -1 1 -1 1
所以 rle(x)$lengths
给你你想要的:
rle(x)$lengths
#[1] 3 1 6 2 2 7 1
@clemlaflemme函数与rle
的效率比较:
library(microbenchmark)
x <- rep(x,5000)
microbenchmark(clem_shift(),cath_rle(),clem_cumul(),unit="relative")
#Unit: relative
# expr min lq mean median uq max neval cld
# clem_shift() 1.000000 1.00000 1.0000000 1.000000 1.000000 1.0000000 100 a
# cath_rle() 1.181513 1.13419 0.8552573 1.095478 1.041918 0.9483564 100 a
# clem_cumul() 325.480391 284.14827 170.1371421 265.160409 241.954976 54.5240969 100 b
仅供参考,您本可以自己编写一小段代码来解决这个问题
cumul = c()
cur = 1
for(i in 2:length(x)){
if(x[i] == x[i-1]) cur = cur + 1
else{
cumul = c(cumul, cur)
cur = 1
}
}
cumul = c(cumul, cur)
当然,使用rle
函数更简单。在@CathG 评论之后,如果只使用 0 和 1,您可能会想到另一个手写函数:
clem = function(X){
shift = c(0,seq(X)[as.logical(c(X[-1] - head(X,-1), 1))])
shift = shift[-1] - head(shift,-1)
return(shift)
}
然后是针对 rle
的基准:
X = runif(1000)<0.5
> microbenchmark(cath(),clem(),unit = "relative")
Unit: relative
expr min lq mean median uq max neval
cath() 1.115647 1.10824 1.220533 1.102692 1.098195 9.22847 100
clem() 1.000000 1.00000 1.000000 1.000000 1.000000 1.00000 100
例如,我有一个这样的矢量:
x<-c(1,1,1, -1, 1,1,1,1,1,1, -1,-1, 1,1, -1,-1,-1,-1,-1,-1,-1, 1)
我希望算法生成一个向量 (3,1,6,2,2,7,1)
表示 3 个“1”、1 个“-1”、6 个“1”等...
我开发了以下算法,但它不适用于每个向量 x,我可能会使用它。
y<-c(0)
q=0
z=0
w=0
e=1
if (x[1]==1)
{
q<-abs(sum(x[1:(min(which(x < 0))-1)]))
y[e]<-q
k=q+1
z<-abs(sum(x[k:min(which(x < 0))]))
e=e+1
y[e]<-z
k=k+z
r<-matrix(c(which(x < 0)))
w<-matrix(c(which(x > 0)))
while( k<22 )
{
if( all(r<k) )
{
z<-sum(x[k:22])
e=e+1
y[e]<-z
k=k+z
}else
{
z<-abs(sum(x[k:min(r[which(r > k)]-1)]))
e=e+1
y[e]<-z
k=k+z
}
if( all(w<k) )
{
z<-abs(sum(x[k:22]))
e=e+1
y[e]<-z
k=k+z
}else
{z<-abs(sum(x[k:min(w[which(w > k)]-1)]))
e=e+1
y[e]<-z
k=k+z
}
}}
但是对于向量
x<-c(1,1,1, -1, 1,1,1,1,1,1, -1,-1, 1,1, -1,-1,-1,-1,-1,-1,-1,-1)
它有效。
您是否有任何想法可以更快更轻松地执行此操作,或者只是在我自己的代码中找到问题?
谢谢大家!
你可以尝试函数 rle
:
rle(x)
#Run Length Encoding
# lengths: int [1:7] 3 1 6 2 2 7 1
# values : num [1:7] 1 -1 1 -1 1 -1 1
所以 rle(x)$lengths
给你你想要的:
rle(x)$lengths
#[1] 3 1 6 2 2 7 1
@clemlaflemme函数与rle
的效率比较:
library(microbenchmark)
x <- rep(x,5000)
microbenchmark(clem_shift(),cath_rle(),clem_cumul(),unit="relative")
#Unit: relative
# expr min lq mean median uq max neval cld
# clem_shift() 1.000000 1.00000 1.0000000 1.000000 1.000000 1.0000000 100 a
# cath_rle() 1.181513 1.13419 0.8552573 1.095478 1.041918 0.9483564 100 a
# clem_cumul() 325.480391 284.14827 170.1371421 265.160409 241.954976 54.5240969 100 b
仅供参考,您本可以自己编写一小段代码来解决这个问题
cumul = c()
cur = 1
for(i in 2:length(x)){
if(x[i] == x[i-1]) cur = cur + 1
else{
cumul = c(cumul, cur)
cur = 1
}
}
cumul = c(cumul, cur)
当然,使用rle
函数更简单。在@CathG 评论之后,如果只使用 0 和 1,您可能会想到另一个手写函数:
clem = function(X){
shift = c(0,seq(X)[as.logical(c(X[-1] - head(X,-1), 1))])
shift = shift[-1] - head(shift,-1)
return(shift)
}
然后是针对 rle
的基准:
X = runif(1000)<0.5
> microbenchmark(cath(),clem(),unit = "relative")
Unit: relative
expr min lq mean median uq max neval
cath() 1.115647 1.10824 1.220533 1.102692 1.098195 9.22847 100
clem() 1.000000 1.00000 1.000000 1.000000 1.000000 1.00000 100