下面是我的R代码,它采用向量a并返回向量b。向量b应该是具有特定格式的向量a的唯一标识符。请注意,a的所有相同数字彼此相邻排序。
a <- c(1, 1, 1, 2, 2, 2, 3, 4, 5, 6, 6, 6, 6, 7, 8, 9, 9)
b <- NULL
for(i in 5:length(a)){
if (a[i] == a[i - 1] & a[i] == a[i - 2] & a[i] == a[i - 3] & a[i] == a[i - 4])
b[i] <- paste(a[i], "-", 4, sep="")
else if (a[i] == a[i - 1] & a[i] == a[i - 2] & a[i] == a[i - 3])
b[i] <- paste(a[i], "-", 3, sep="")
else if (a[i] == a[i - 1] & a[i] == a[i - 2])
b[i] <- paste(a[i], "-", 2, sep="")
else if (a[i] == a[i - 1])
b[i] <- paste(a[i], "-", 1, sep="")
else
b[i] <- paste(a[i], "-", 0, sep="")
}
#The first 4 values in vector b have to manually entered
#because the for loop checks up to 4 consecutive numbers in a
b[1] <- "1-0"
b[2] <- "1-1"
b[3] <- "1-2"
b[4] <- "2-0"
b
上面的代码根据需要返回b,但是,如果向量a具有多于4个相同的连续数,则for循环将产生包含一些相同元素的b。如何改进这种for循环,以便可以为任何数量的相同连续数字赋予适当的唯一标识符。
我正在考虑使用某种嵌套的for循环,但是如何在if语句中完成呢?
答案 0 :(得分:5)
这可能会取代您当前的循环。 rle()
用于为a
的每个唯一元素构造一个序列,从零开始。然后我们可以paste()
与-
分隔符一起paste(a, sequence(rle(a)$lengths) - 1, sep = "-")
# [1] "1-0" "1-1" "1-2" "2-0" "2-1" "2-2" "3-0" "4-0" "5-0" "6-0" "6-1"
# [12] "6-2" "6-3" "7-0" "8-0" "9-0" "9-1"
。
b
与{{1}}
的输出相同答案 1 :(得分:3)
使用ave
和paste
,我现在意识到这只是@ RichardScriven答案的变体:
paste(a, ave(a,a,FUN=seq_along) - 1, sep="-")
# [1] "1-0" "1-1" "1-2" "2-0" "2-1" "2-2" "3-0" "4-0" "5-0" "6-0" "6-1"
#[12] "6-2" "6-3" "7-0" "8-0" "9-0" "9-1"
答案 2 :(得分:1)
# If you are sure the different groups are really sorted, this will work:
b <- tapply(1:length(a), a, FUN = function(x) (1:length(x)) -1 )
b <- paste(a, unlist(b), sep = "-")