按顺序改变重复

时间:2012-05-31 18:44:20

标签: arrays r

我有以下载体

328 328 328 328 337 338 339 340 341 342 343 344 345 346 347 348 349 349 349 349 349 349 349 349 349 349 349 349

如您所见,328重复4次,349重复12次。我想知道R中最有效的方法是将328重新编号为328,329,330,331,而349则为349,350,351 ......

我可以使用for循环来做到这一点,但我有一种感觉R有一种更“以R为中心”的方法。

3 个答案:

答案 0 :(得分:4)

如果这是数据

x = c(rep(328, 4), rep(349, 12))

您可以对其进行运行长度编码表示

r = rle(x)

然后创建等于每次运行长度的序列

s = lapply(r$lengths, seq_len)

最后将这些添加到原始数据(减1,因为在上一步中创建的序列从1开始)

unlist(Map("+", s, r$values - 1)

所以

> r = rle(x)
> unlist(Map("+", lapply(r$lengths, seq_len), r$values - 1))
 [1] 328 329 330 331 349 350 351 352 353 354 355 356 357 358 359 360

(@ DWin使用seq更清晰。如果尚未按顺序排列x的值,那么这是有意义的。

> (x = sample(x))
 [1] 349 349 349 349 349 349 328 349 349 328 328 328 349 349 349 349
> o = order(x)
> r = rle(x[o])
> unlist(Map(seq, r$values, length=r$length))[order(o)]
 [1] 349 350 351 352 353 354 328 355 356 329 330 331 357 358 359 360

答案 1 :(得分:2)

# Demonstrating efficient way to take comma-less sequence as input from console.

> x <- scan()
 1: 328 328 328 328 337 338 339 340 341 342 343 344 345 346 347 348 349 349 349 349 349 349 349 349 349 349 349 349
29: 
Read 28 items

# Solution
unlist( mapply(seq, rle(x)$values, length=rle(x)$lengths ) )
# [1] 328 329 330 331 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
# [26] 358 359 360

rle看起来似乎是一个明显的起点,但在我看到@MartinMorgan的mapply解决方案之前我没有想到Map方法

答案 2 :(得分:1)

如果vec是您的重复序列

Reduce(function(x,y) if (y %in% x) c(x, max(x) + 1) else c(x, y), vec[order(vec)])