假设我有alpha
alpha = c(a,a,a,b,c,c,c,a,c,c)
如何找到周期性,以便我可以构造另一个数组beta
beta = c(3,1,3,1,2)
没有在代码中使用alpha
的内容?有没有办法使用线索或滞后来回答这个问题?
答案 0 :(得分:1)
以下是使用tabulate
和rleid
library(data.table)
tabulate(rleid(alpha))
#[1] 3 1 3 1 2
答案 1 :(得分:1)
只是为了好玩,这是一个复杂的解决方案:
alpha <- c('a','a','a','b','c','c','c','a','c','c');
diff(c(0L,which(c(alpha[-1L]!=alpha[-length(alpha)],T))));
## [1] 3 1 3 1 2
alpha[-1L]!=alpha[-length(alpha)];
## [1] FALSE FALSE TRUE TRUE FALSE FALSE TRUE TRUE FALSE
首先计算一个逻辑向量,表示哪些相邻的输入元素对构成值相等的中断,哪些不相等。逻辑向量中每个元素的索引对应于输入向量中该对的第一个元素的索引。
c(alpha[-1L]!=alpha[-length(alpha)],T);
## [1] FALSE FALSE TRUE TRUE FALSE FALSE TRUE TRUE FALSE TRUE
附加TRUE
值以在向量的末尾创建伪中断。请参阅下一步以获得澄清。
which(c(alpha[-1L]!=alpha[-length(alpha)],T));
## [1] 3 4 7 8 10
将逻辑向量转换为表示输入向量中运行长度的端点的索引向量。现在应该清楚为什么我们必须在上一步中附加TRUE
;否则将省略最终运行长度的终点。
c(0L,which(c(alpha[-1L]!=alpha[-length(alpha)],T)));
## [1] 0 3 4 7 8 10
前置零。这在概念上可以被认为是将索引向量变换为“边界向量”,其中每个元素表示输入向量运行长度的内部或外部边界。请参阅下一步以获得澄清。
diff(c(0L,which(c(alpha[-1L]!=alpha[-length(alpha)],T))));
## [1] 3 1 3 1 2
取连续边界之间的差异。这提供了所需的运行长度。
library(data.table);
library(microbenchmark);
bgoldst <- function(alpha) diff(c(0L,which(c(alpha[-1L]!=alpha[-length(alpha)],T))));
akrun <- function(alpha) tabulate(rleid(alpha));
bethany <- function(alpha) { if (length(alpha)==0L) return(integer()); res <- integer(); last <- alpha[1L]; cnt <- 1L; i <- 2L; while (i<=length(alpha)) { if (alpha[i]==last) cnt <- cnt+1L else { res[length(res)+1L] <- cnt; last <- alpha[i]; cnt <- 1L; }; i <- i+1L; }; res[length(res)+1L] <- cnt; res; };
flick <- function(alpha) rle(alpha)$lengths;
alpha <- c('a','a','a','b','c','c','c','a','c','c');
expected <- c(3L,1L,3L,1L,2L);
identical(expected,bgoldst(alpha));
## [1] TRUE
identical(expected,akrun(alpha));
## [1] TRUE
identical(expected,bethany(alpha));
## [1] TRUE
identical(expected,flick(alpha));
## [1] TRUE
microbenchmark(bgoldst(alpha),akrun(alpha),bethany(alpha),flick(alpha));
## Unit: microseconds
## expr min lq mean median uq max neval
## bgoldst(alpha) 8.553 11.1200 14.85308 12.8300 15.3970 70.136 100
## akrun(alpha) 129.151 144.9745 163.64182 156.7350 171.4895 313.898 100
## bethany(alpha) 20.101 23.9500 30.43242 26.5155 37.8475 70.136 100
## flick(alpha) 20.100 23.9495 30.44956 28.0120 32.2890 62.866 100
set.seed(1L); N <- 1e5L; alpha <- sample(letters[1:3],N,T);
expected <- bgoldst(alpha);
identical(expected,akrun(alpha));
## [1] TRUE
identical(expected,bethany(alpha));
## [1] TRUE
identical(expected,flick(alpha));
## [1] TRUE
microbenchmark(bgoldst(alpha),akrun(alpha),bethany(alpha),flick(alpha),times=10L);
## Unit: milliseconds
## expr min lq mean median uq max neval
## bgoldst(alpha) 5.497899 6.469098 11.007558 6.521699 7.297460 49.891634 10
## akrun(alpha) 1.300492 1.370199 1.547461 1.401631 1.464282 2.816091 10
## bethany(alpha) 2865.335271 2891.594408 2941.352229 2924.165053 2997.881411 3024.234204 10
## flick(alpha) 8.060392 9.355323 13.646002 10.055176 10.841843 48.312741 10
答案 2 :(得分:0)
如果你想保持alpha盲区的值,你可以创建一个for循环并使用逻辑运行一个计数器,如果这个alpha迭代等于最后一个。您需要设置过去的alpha以接受当前值并将下一个值与之比较。
一旦两个值不一致,计数器编号就会连接到您在循环外创建的向量,计数器将返回到一个。
这很简单,你应该自己去做,以了解如何做。
您可以将文件读入变量,但不能手动输入数字或者需要使它们可见。如果数据受到保护&#39;在某种程度上...