我有一个包含1到5个重复值的向量,后面是另一个这样的集合,通常但不总是加1。例如,
c(1,1,1,1,1, 2,2,2,2, 3,3, 4,4,4,4,4)
我想对此进行操作,只有在重复给出时才为每个值添加0.2的增量
c(1,1.2,1.4,1.6,1.8, 2,2.2,2.4,2.6, 3,3.2, 4,4.2,4.4,4.6,4.8)
我可以通过使用for循环很容易地做到这一点,但我的初始向量长度超过100万条,这需要相当长的时间。我一直试图想出一个没有运气的基于列表的方法。任何建议将不胜感激。
答案 0 :(得分:7)
这是一种使用rle
和序列创建序列0,0.2,0.4,....
的方法,并将其添加到原始序列中。
x <- c(1,1,1,1,1, 2,2,2,2, 3,3, 4,4,4,4,4)
x + (sequence(rle(x)$lengths)-1)*0.2
答案 1 :(得分:4)
另一种ave
可能性:
ave(
dat,
c(0,cumsum(diff(dat)!=0)),
FUN=function(x) x + seq(0,(length(x)-1)*0.2,0.2)
)
#[1] 1.0 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 3.0 3.2 4.0 4.2 4.4 4.6 4.8
答案 2 :(得分:3)
这是一种可能性(假设每个数字的集合永远不会超过每个数字,并且每个数字最多重复5次):
myvec <- c(1,1,1,1,1, 2,2,2,2, 3,3, 4,4,4,4,4)
myvec + seq(0, .8, .2)[ave(myvec, myvec, FUN = seq_along)]
# [1] 1.0 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 3.0 3.2 4.0 4.2 4.4 4.6 4.8
为了在处理向量中的重复数字时有更好的选择,请参阅@ mnel和@thelatemail的答案....
答案 3 :(得分:1)
对于非常大的连锁店来说,这可能会很快。
编辑 - 使用head填充c_prev,而不是tail。感谢@Ricardosaporta将其指出
library(data.table)
test <- data.table(
c1 = c(1,1,1,1,1, 2,2,2,2, 3,3, 4,4,4,4,4)
)
test[,c_prev := c(NA,head(c1,-1))]
test[, increment := 0.0]
test[c1 == c_prev , increment := 0.2]
test[, cumincrement := cumsum(increment), by = c1]
test[, revised_c := c1]
test[!is.na(cumincrement), revised_c := revised_c + cumincrement]
test
# c1 c_prev increment cumincrement revised_c
# 1: 1 NA 0.0 0.0 1.0
# 2: 1 1 0.2 0.2 1.2
# 3: 1 1 0.2 0.4 1.4
# 4: 1 1 0.2 0.6 1.6
# 5: 1 1 0.2 0.8 1.8
# 6: 2 1 0.0 0.0 2.0
# 7: 2 2 0.2 0.2 2.2
# 8: 2 2 0.2 0.4 2.4
# 9: 2 2 0.2 0.6 2.6
#10: 3 2 0.0 0.0 3.0
#11: 3 3 0.2 0.2 3.2
#12: 4 3 0.0 0.0 4.0
#13: 4 4 0.2 0.2 4.2
#14: 4 4 0.2 0.4 4.4
#15: 4 4 0.2 0.6 4.6
#16: 4 4 0.2 0.8 4.8