R中列的每一个变化都增加1
可以说我有以下数据框
set.seed(123) df <- data.frame(var1=(runif(10)>0.5)*1)   var1可以具有任何types/数量的级别,不具体为0和1 
 我想创build一个var2 ,每次var1改变时都会增加1, 而不使用for loop 
预期的结果是:
 data.frame(var1=(runif(10)>0.5)*1, var2=c(1, 2, 3, 4, 4, 5, 6, 6, 6, 7)) var1 var2 0 1 1 2 0 3 1 4 1 4 0 5 1 6 1 6 1 6 0 7 
数据框的另一种select可能是:
 df <- data.frame(var1=c("a", "a", "1", "0", "b", "b", "b", "c", "1", "1")) 
在这种情况下,结果应该是:
 var1 var2 a 1 a 1 1 2 0 3 b 4 b 4 b 4 c 5 1 6 1 6 
	
在Flick先生的基础上回答:
 df$var2 <- cumsum(c(0,as.numeric(diff(df$var1))!=0)) 
 但是,如果你不想使用diff你仍然可以使用: 
 df$var2 <- c(0,cumsum(as.numeric(with(df,var1[1:(length(var1)-1)] != var1[2:length(var1)])))) 
它从0开始,而不是1,但我相信你会看到如何改变它,如果你想。
 如何使用diff()和cumsum() 。 例如 
 df$var2 <- cumsum(c(1,diff(df$var1)!=0)) 
这些看起来像一个游程编码(rle)
 x = c("a", "a", "1", "0", "b", "b", "b", "c", "1", "1") r = rle(x) 
同
 > rle(x) Run Length Encoding lengths: int [1:6] 2 1 1 3 1 2 values : chr [1:6] "a" "1" "0" "b" "c" "1" 
这就是说,第一个值(“a”)连续出现两次,然后“1”出现一次,等等。你要做的是沿着“长度”创build一个序列,并复制序列的每个元素元素出现的次数,所以
 > rep(seq_along(r$lengths), r$lengths) [1] 1 1 2 3 4 4 4 5 6 6 
其他答案是半欺骗性的,因为他们依赖于列是一个因素(); 当列实际上是一个字符()时,它们失败。
 > diff(x) Error in r[i1] - r[-length(r):-(length(r) - lag + 1L)] : non-numeric argument to binary operator 
一个解决方法是将字符映射到整数,沿着
 > diff(match(x, x)) [1] 0 2 1 1 0 0 3 -5 0 
嗯,但是说过我发现这个问题不能解决问题。
 > f = factor(x) > rle(f) Error in rle(factor(x)) : 'x' must be a vector of an atomic type > rle(as.vector(f)) Run Length Encoding lengths: int [1:6] 2 1 1 3 1 2 values : chr [1:6] "a" "1" "0" "b" "c" "1" 
 这里是使用inverse.rle()另一个使用base R的解决scheme: 
 df <- data.frame(var1=c("a", "a", "1", "0", "b", "b", "b", "c", "1", "1")) r <- rle(as.character(df$var1)) r$values <- seq_along(r$values) df$var2 <- inverse.rle(r) 
简短版本:
 df$var2 <- with(rle(as.character(df$var1)), rep(seq_along(values), lengths)) 
 这是data.table的解决scheme: 
 library("data.table") dt <- data.table(var1=c("a", "a", "1", "0", "b", "b", "b", "c", "1", "1")) dt[, var2:=rleid(var1)]