2014-09-04 33 views
0

如何與ID組突變列如何與ID突變的列組

data.frame像:

a b c 
1 a 1 1 
2 a 1 2 
3 a 2 3 
4 b 1 4 
5 b 2 5 
6 b 3 6 

組由一個,標誌1開始,如果b等於預b,則標誌= 1個else標誌+ = 1

a b c flag 
1 a 1 1 1 <- group a start with 1 
2 a 1 2 1 <-- in group a, 1(in row 2)=1(in row 1) 
3 a 2 3 2 <- in group a, 2(in row 3)!=1(in row 2) 
4 b 1 4 1 <- group b start with 1 
5 b 2 5 2 <- in group b, 2(in row 5)!=1(in row 4) 
6 b 3 6 3 <- in group b, 3(in row 6)!=2(in row 5) 
+0

這是一個有點電報(或Twitter)風格annd有在本例中的錯誤,但除此之外,這是一個明確的問題。我想念的唯一一件事是「我試過了,但沒有奏效」。 – 2014-09-04 10:18:37

回答

1

我不完全確定你正在嘗試做什麼。但在我看來,你正試圖將索引號分配給b中每個組的值(a或b)。

#I modified your example here. 

a <- rep(c("a","b"), each =3) 
b <- c(4,4,5,11,12,13) 
c <- 1:6 

foo <- data.frame(a,b,c, stringsAsFactors = F) 

    a b c 
1 a 4 1 
2 a 4 2 
3 a 5 3 
4 b 11 4 
5 b 12 5 
6 b 13 6 

#Since you referred to dplyr, I will use it. 

cats <- list() 
for(i in unique(foo$a)){ 

ana <- foo %>% 
     filter(a == i) %>% 
     arrange(b) %>% 
     mutate(indexInb = as.integer(as.factor(b))) 

cats[[i]] <- ana 

} 

bob <- rbindlist(cats) 

    a b c indexInb 
1: a 4 1  1 
2: a 4 2  1 
3: a 5 3  2 
4: b 11 4  1 
5: b 12 5  2 
6: b 13 6  3 
2

我現在使用這樣的:

for(i in 2:nrow(x)){ 
    x[i, 'flag'] = ifelse(x[i, 'a']!=x[i-1,'a'], 1, ifelse(x[i, 'b']==x[i-1, 'b'], x[i-1, 'flag'], x[i-1,'flag']+1)) 
} 

但它是效率低下的大型數據集

UPDATE

dense_rank在dplyr給我答案

> x %>% group_by(a) %>% mutate(dense_rank(b)) 
Source: local data frame [10 x 4] 
Groups: a 

    a b c dense_rank(b) 
1 a x 1    1 
2 a x 2    1 
3 a y 3    2 
4 b x 4    1 
5 b y 5    2 
6 b z 6    3 
7 c x 7    1 
8 c y 8    2 
9 c z 9    3 
10 c z 10    3 

感謝。

1

赫斯是解決這一不使用任何for循環

基礎R解決方案使用avetransform

transform(x, flag = ave(b, a, FUN = function(x) cumsum(c(1, diff(x))))) 
# a b c flag 
# 1 a 1 1 1 
# 2 a 1 2 1 
# 3 a 2 3 2 
# 4 b 1 4 1 
# 5 b 2 5 2 
# 6 b 3 6 3 

還是一個data.table溶液(更有效)的快速量化的方式

library(data.table) 
setDT(x)[, flag := cumsum(c(1, diff(b))), by = a] 
x 
# a b c flag 
# 1: a 1 1 1 
# 2: a 1 2 1 
# 3: a 2 3 2 
# 4: b 1 4 1 
# 5: b 2 5 2 
# 6: b 3 6 3 

dplyr解決方案(因爲你標記它)

library(dplyr) 
x %>% 
    group_by(a) %>% 
    mutate(flag = cumsum(c(1, diff(b)))) 
# Source: local data frame [6 x 4] 
# Groups: a 
# 
# a b c flag 
# 1 a 1 1 1 
# 2 a 1 2 1 
# 3 a 2 3 2 
# 4 b 1 4 1 
# 5 b 2 5 2 
# 6 b 3 6 3 
+0

抱歉,我沒有清楚地說明我的問題。列b可以是像c('a','a','b','a','b','c')那樣的字符。但還是謝謝。我使用'x%>%mutate(dense_rank(b))'來解決它。 – funnng 2014-09-04 10:23:48

+0

在你的數據框中粘貼的最快路徑是'x $ flag = dense_rank(x $ b)',你不需要任何管道。 – Spacedman 2014-09-04 10:30:00

+0

@spacedman - pfft ...更多管請。 – thelatemail 2014-09-04 10:34:41