从R中的向量中提取交替序列
Extracting alternating sequence from vector in R
我的数据如下所示:
A= c(0,0,0,-1,0,0,0,1,1,1,0,0,-1,0,0,-1,-1,1,1,1,-1,0,0,0,-1,0,0,-1,-1,1,1,0,0,0,0,1,-1)
目标是提取交替的 -1 和 1。我想创建一个函数,其中输入向量包含 0,1 和 -1。理想情况下,输出吐出所有 0 和交替的 -1 和 1。
例如,上述示例的所需输出是:
B= c(0,0,0,-1,0,0,0,1,0,0,0,0,-1,0,0,0,0,1,0,0,-1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,-1)
A中第9个和第10个位置的两个1变为0,因为我们只保留第一个1或-1出现。 A的第16、17位的-1也因为这个原因变成了0
谁有制作这样一个功能的好主意?
您必须滑动所有数组并使用标志变量检查您之前是否找到 1 或 -1。
可能是伪代码算法:
while i < length(a):
if flag == 1 && a[i]=-1:
b[i]=a[i];
flag = -1;
else if flag == -1 && a[i] = 1:
b[i]=a[i];
flag = 1;
else:
b[i]=0;
i++;
}//end of while
这实际上只是 GWarius 伪代码的具体化。 (我已经有了一个结构,但逻辑失败了。)
last1 <- -A[which(A != 0)[1] ] # The opposite of the first non-zero item
for (i in seq_along(A) ){
if( last1==1 && A[i]==-1 ){ last1 <- -1
} else {if (last1 == -1 && A[i] == 1) { last1 <- 1
} else {A[i] <- 0}} }
A
[1] 0 0 0 -1 0 0 0 1 0 0 0 0 -1 0 0 0 0 1 0 0 -1 0 0
[24] 0 0 0 0 0 0 1 0 0 0 0 0 0 -1
> identical(A, B)
[1] TRUE
识别非零值的位置:
w = which(A != 0)
对于每个运行相似的值,在A[w]
中,取第一个的位置:
library(data.table)
wkeep = tapply(w, rleid(A[w]), FUN = function(x) x[1])
将所有其他值设置为零:
# following @alexis_laz's approach
B = numeric(length(A))
B[ wkeep ] = A[ wkeep ]
这样,您就不必在循环中进行比较,我认为 R 在这方面很慢。
rleid
来自 data.table。使用 base R,您可以根据@alexis_laz 的建议制作 wkeep
:
wkeep = w[c(TRUE, A[w][-1L] != A[w][-length(w)])]
或者自己写 rleid
,如 。
我的数据如下所示:
A= c(0,0,0,-1,0,0,0,1,1,1,0,0,-1,0,0,-1,-1,1,1,1,-1,0,0,0,-1,0,0,-1,-1,1,1,0,0,0,0,1,-1)
目标是提取交替的 -1 和 1。我想创建一个函数,其中输入向量包含 0,1 和 -1。理想情况下,输出吐出所有 0 和交替的 -1 和 1。
例如,上述示例的所需输出是:
B= c(0,0,0,-1,0,0,0,1,0,0,0,0,-1,0,0,0,0,1,0,0,-1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,-1)
A中第9个和第10个位置的两个1变为0,因为我们只保留第一个1或-1出现。 A的第16、17位的-1也因为这个原因变成了0
谁有制作这样一个功能的好主意?
您必须滑动所有数组并使用标志变量检查您之前是否找到 1 或 -1。 可能是伪代码算法:
while i < length(a):
if flag == 1 && a[i]=-1:
b[i]=a[i];
flag = -1;
else if flag == -1 && a[i] = 1:
b[i]=a[i];
flag = 1;
else:
b[i]=0;
i++;
}//end of while
这实际上只是 GWarius 伪代码的具体化。 (我已经有了一个结构,但逻辑失败了。)
last1 <- -A[which(A != 0)[1] ] # The opposite of the first non-zero item
for (i in seq_along(A) ){
if( last1==1 && A[i]==-1 ){ last1 <- -1
} else {if (last1 == -1 && A[i] == 1) { last1 <- 1
} else {A[i] <- 0}} }
A
[1] 0 0 0 -1 0 0 0 1 0 0 0 0 -1 0 0 0 0 1 0 0 -1 0 0
[24] 0 0 0 0 0 0 1 0 0 0 0 0 0 -1
> identical(A, B)
[1] TRUE
识别非零值的位置:
w = which(A != 0)
对于每个运行相似的值,在A[w]
中,取第一个的位置:
library(data.table)
wkeep = tapply(w, rleid(A[w]), FUN = function(x) x[1])
将所有其他值设置为零:
# following @alexis_laz's approach
B = numeric(length(A))
B[ wkeep ] = A[ wkeep ]
这样,您就不必在循环中进行比较,我认为 R 在这方面很慢。
rleid
来自 data.table。使用 base R,您可以根据@alexis_laz 的建议制作 wkeep
:
wkeep = w[c(TRUE, A[w][-1L] != A[w][-length(w)])]
或者自己写 rleid
,如