基于R中的顺序值标记组的最有效方法

时间:2014-08-04 19:38:08

标签: r

在我的工作中,我在不同的环境中反复遇到过这种类型的任务。我过去曾经使用各种方法解决它(通常是滞后,差异等一些尴尬的组合),但一直认为必须有更好,更通用,更有效的方法。目标是基于另一个变量的顺序变化在新变量中标记组。例如:

var1a <- c("A","A","B","B","B","C","D","D","D","D","D")

应该会产生一个标记四组的新变量:

var2a <- c(1, 1, 2, 2, 2, 3, 4, 4, 4, 4, 4)

稍微不那么简单,这应该基于序列中相同值的分组,而不仅仅是var1的唯一值。例如:

var1b <- c(1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0)

应该会产生一个标记四组的新变量:

var2b <- c(1, 1, 1, 2, 2, 3, 4, 4, 4, 4, 4, 4)

并澄清,当我说&#34;有效&#34;我对简单/可读/健壮/通用比对计算效率更感兴趣,尽管这也有一些重要性。

3 个答案:

答案 0 :(得分:3)

您可以使用行程编码(?rle):

var1a <- c("A","A","B","B","B","C","D","D","D","D","D")
z     <- rle(var1a)
var2a <- rep(1:length(z$lengths),z$lengths)
var2a
#  [1] 1 1 2 2 2 3 4 4 4 4 4

var1b <- c(1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0)
z <- rle(var1b)
var2b <- rep(1:length(z$lengths),z$lengths)
var2b
#  [1] 1 1 1 2 2 3 4 4 4 4 4 4

或者,更一般地说,

get.groups <- function(x) with(rle(x),rep(1:length(lengths),lengths))
get.groups(var1a)
#  [1] 1 1 2 2 2 3 4 4 4 4 4
get.groups(var1b)
#  [1] 1 1 1 2 2 3 4 4 4 4 4 4

答案 1 :(得分:0)

要回答第一个问题,我尝试以下方法:

var2a <- as.integer(factor(var1a))

对于第二个问题,我会使用@ jlhoward建议使用rle

答案 2 :(得分:0)

我打算回应史蒂夫·科恩关于将因子强加给数字的建议,但是将其用于第二个Q:

> cumsum(c(1, diff(var1b)!=0))
 [1] 1 1 1 2 2 3 4 4 4 4 4 4

我想指出这个问题含糊不清w.r.t.

的首要问题是什么?
var1a <- c("A","A","B","B","B","C","D","D","D","D","D", "a", "A", "B", "B")

rle方法将提供与factor方法不同的答案。