2012-10-29 110 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

不客氣。我喜歡讓人開心! ;-) –