矢量A:
a = c(0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1)
向量B :(仅用于初始化)
b = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
数据帧:
dft <- data.frame(a,b)
下面的for循环比较每行“i”的值A [i]和向量A中的A [i + 1]。 如果i + 1不同 - >写“计数” 否则检查i + 2并增加“count”......
我们的想法是知道每一行的行数,直到A中的值发生变化。
count = 0
%需要无穷无尽(对于大型集合)但是能够完成其工作
for(i in 1:nrow(dft)) {
for(j in i+1:nrow(dft)-1) {
j_value <- dft[j,"a"]
i_value <- dft[i,"a"]
if (!is.na(j_value) & !is.na(i_value)){
tmp_value <- abs(i_value - j_value)
if(tmp_value > 0) {
dft[i,"b"] <- count
count = 0
break
} else {
count = count + 1
}
}
}
}
结果应该是:
b
1: 5
2: 4
3: 3
4: 2
5: 1
6: 1
7: 2
8: 1
9: 3
10: 2
11: 1
12: 5
13: 4
14: 3
15: 2
16: 1
17: 0
答案 0 :(得分:2)
以下内容应该有效:
b = rle(a)
unlist(mapply(":", b$lengths, 1))
# [1] 5 4 3 2 1 1 2 1 3 2 1 5 4 3 2 1 1
或者在一行中:
with(rle(a), unlist(Map(":", lengths, 1)))
使用“data.table”,您可以执行以下操作:
library(data.table)
data.table(a)[, b := .N:1, rleid(a)][]
# a b
# 1: 0 5
# 2: 0 4
# 3: 0 3
# 4: 0 2
# 5: 0 1
# 6: 1 1
# 7: 0 2
# 8: 0 1
# 9: 1 3
# 10: 1 2
# 11: 1 1
# 12: 0 5
# 13: 0 4
# 14: 0 3
# 15: 0 2
# 16: 0 1
# 17: 1 1
答案 1 :(得分:1)
使用data.table
如何做到这一点。有一些反向排序,并使用shift
将值与后续值进行比较。它可能有点复杂,但似乎有效。
library( data.table )
dft <- data.table(a)
dft[ , f := shift( a, 1L, fill = F, type = "lead" ) != a
][ .N:1, b := seq_len(.N), by = cumsum(f)
][ , f := NULL ]
dft
a b
1: 0 5
2: 0 4
3: 0 3
4: 0 2
5: 0 1
6: 1 1
7: 0 2
8: 0 1
9: 1 3
10: 1 2
11: 1 1
12: 0 5
13: 0 4
14: 0 3
15: 0 2
16: 0 1
17: 1 1
答案 2 :(得分:0)
以下是适用的另一种方法:
# The data
a=c(0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1)
# An index of the data
ind <- 1:length(a)
# The function to apply
f <- function(x){ifelse(!is.na(which(a[x]!=a[x:length(a)])[1] - 1), # Check if we are in the last group before series ends
which(a[x]!=a[x:length(a)])[1] - 1, # if not return distance to nearest value change
ind[length(a)] - x + 1) # if we are return length of last block of values
}
unlist(lapply(ind, f)) # Apply and unlist to vector
#> [1] 5 4 3 2 1 1 2 1 3 2 1 5 4 3 2 1 1
如果您希望将其减少到which()
语句,在这种情况下,最后一块同质值将被赋予NA。根据上下文的不同,您可能需要使用不同的方法来处理最后一个块,因为重复值的重复次数会被审查(可能您希望在ifelse的第二项中提供字符串,如'1+')。