R中的部分向量加法

时间:2013-09-27 04:00:38

标签: r

我有一个包含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万条,这需要相当长的时间。我一直试图想出一个没有运气的基于列表的方法。任何建议将不胜感激。

4 个答案:

答案 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