2012-10-29 75 views
7

计数变量I有R数据帧:计算在数据帧

a <- 1:12 
list <- c(rep("x",3),rep("y",4),rep("z",3),rep("x",2)) 
data <- data.frame(a,list) 

data 
a list 
1 x 
2 x 
3 x 
4 y 
5 y 
6 y 
7 y 
8 z 
9 z 
10 z 
11 x 
12 x 

我想创建开始于1每次的在这个例子中“列表”的变化,即,值计数一个新的列:

b <- c(1:3,1:4,1:3,1:2)  
data <- data.frame(a,list,b) 

我不是一个在R的专家,不能为我的生活制定一个有效的方式来做到这一点。我的主要问题似乎是,任何“list”值都可以随时返回,但是对于一个值的块的长度没有规定。 有没有人有任何想法? 谢谢!

+4

就评论这个包起来:它往往是一个好主意,不使用内置的名字(例如'data'或'list')作为变量名 - 如果后面想要使用'list()'函数,则可能会遇到非常奇怪的错误。 –

+0

事实上,大多数人不会称呼他们的狗“狗”!例如。 –

+0

是的,你是对的。从现在开始我会记住这一点。 –

回答

5

我会用rle()得到的list运行的长度,然后使用得心应手sequence()函数生成由rle()返回$lengths组件所需的计数器:

R> sequence(rle(as.character(data$list))$lengths) 
[1] 1 2 3 1 2 3 4 1 2 3 1 2 

注意我们必须将list转换为原子向量(在我的情况下是字符向量),因为在rle()中不允许使用因子。

要它放入data,然后在通话中,如

data <- transform(data, b = sequence(rle(as.character(list))$lengths)) 

这给

R> data <- transform(data, b = sequence(rle(as.character(list))$lengths)) 
R> data 
    a list b 
1 1 x 1 
2 2 x 2 
3 3 x 3 
4 4 y 1 
5 5 y 2 
6 6 y 3 
7 7 y 4 
8 8 z 1 
9 9 z 2 
10 10 z 3 
11 11 x 1 
12 12 x 2 
+0

完美,谢谢! –

+0

@ user1777393如果您对答案感到满意,请考虑接受其中一个答案。使用您希望接受的答案旁边的大勾号。 [so] faq的[问]部分解释了如何做到这一点,以及为什么这样做会有帮助/有用。 –

+0

谢谢。您可能会注意到我之前没有这样做过。 –

5

关键的想法是使用rle()(运行长度编码)在data$list(将它强制转换为原子向量 - 毕竟,我们对特定条目不感兴趣)。然后我们使用seq()来创建从1开始到结束于计算的运行长度的序列。最后,我们贴上所有这些序列在一起:

unlist(lapply(rle(as.numeric(data$list))$lengths,FUN=seq,from=1)) 
+0

谢谢!这正是我需要的。我不知道这个功能,所以你让我很开心。 –

+0

不客气。我喜欢让人开心! ;-) –