2016-11-24 48 views
2

我的數據框看起來是這樣的:如何data.table與循環結合

> data <- data.frame(A=c(1,1,1,2,2,3,3,3,3,3), B=c("1A","1B","1C","2A","2B","3A","3B","3C","3D","3E")) 

我要添加標記的變量A的功能和B.一個新變量的結果必然是:

> data 
    A B LABEL 
1 1 1A 1-2 
2 1 1B 2-3 
3 1 1C 3-4 
4 2 2A 1-2 
5 2 2B 2-3 
6 3 3A 1-2 
7 3 3B 2-3 
8 3 3C 3-4 
9 3 3D 4-5 
10 3 3E 5-6 

我用data.table函數試試這個。代碼我嘗試:

> setDT(data) 
> data <- data[,list(LABEL = for(i in 1:length(A)){paste(i, "-", i+1, sep="")}),by=c("A","B")] 

消息錯誤:「錯誤[.data.table(數據,列表(LABEL =爲(I在1:長度(A)){: 1 J的結果的第一列我們依靠第一個結果的列類型來決定剩餘組的預期類型(並且需要一致性)。對於後面的組,可以接受NULL列(並且這些列被替換爲適當類型的NA並被回收),但是而不是第一個,請使用類型化的空向量,例如integer()或numeric()。

回答

3

我們可以使用shift創建'lead'值由 'A' 分組後的序列,並paste它與行的順序來創建 '標籤'

library(data.table) 
setDT(data)[, LABEL := paste(seq_len(.N), shift(seq_len(.N), 
          type='lead', fill= .N+1), sep="-"), by = A] 

或者

setDT(data)[, LABEL := paste(seq_len(.N), seq_len(.N)+1, sep = "-"), by = A] 
data 
# A B LABEL 
# 1: 1 1A 1-2 
# 2: 1 1B 2-3 
# 3: 1 1C 3-4 
# 4: 2 2A 1-2 
# 5: 2 2B 2-3 
# 6: 3 3A 1-2 
# 7: 3 3B 2-3 
# 8: 3 3C 3-4 
# 9: 3 3D 4-5 
#10: 3 3E 5-6 

或者我們可以使用base R方法

i1 <- sequence(tabulate(data$A)) 
data$LABEL <- paste(i1, i1+1, sep="-") 
data$LABEL 
#[1] "1-2" "2-3" "3-4" "1-2" "2-3" "1-2" "2-3" "3-4" "4-5" "5-6" 
+1

完美。有用。非常感謝! @akrun –

3

您也可以使用dplyr :: mutate

library(dplyr) 
data %>% 
     group_by(A) %>% 
     mutate(LABEL=paste(seq_along(A),seq_along(A)+1,sep="-")) 

在這裏,您按A,發現沿着組序列並連接序列+ 1

Source: local data frame [10 x 3] 
Groups: A [3] 

     A  B LABEL 
    <dbl> <fctr> <chr> 
1  1  1A 1-2 
2  1  1B 2-3 
3  1  1C 3-4 
4  2  2A 1-2 
5  2  2B 2-3 
6  3  3A 1-2 
7  3  3B 2-3 
8  3  3C 3-4 
9  3  3D 4-5 
10  3  3E 5-6 
3

另一種辦法是使用base Rave功能

data$LABEL <- ave(data$A, data$A, FUN = function(x) 
             paste0(seq_along(x), "-", seq_along(x)+1)) 
data 
# A B LABEL 
#1 1 1A 1-2 
#2 1 1B 2-3 
#3 1 1C 3-4 
#4 2 2A 1-2 
#5 2 2B 2-3 
#6 3 3A 1-2 
#7 3 3B 2-3 
#8 3 3C 3-4 
#9 3 3D 4-5 
#10 3 3E 5-6