2015-04-07 66 views
8

我有一個簡單的問題有關R.在基於R中匹配條件

聚集值的行組合值

假設我有一個數據幀:

DF <- data.frame(col1=c("Type 1", "Type 1B", "Type 2"), col2=c(1, 2, 3)) 

看起來像這樣:

 col1 col2 
1 Type 1 1 
2 Type 1B 2 
3 Type 2 3 

我注意到我在數據中有Type 1Type 1B,所以我想將Type 1B合併成Type 1

所以我決定使用dplyr

filter(DF, col1=='Type 1' | col1=='Type 1B') %>% 
    summarise(n = sum(col2)) 

但現在我需要保持它去:

DF2 <- data.frame('Type 1', filter(DF, col1=='Type 1' | col1=='Type 1B') %>% 
    summarise(n = sum(col2))) 

我想我要cbind這個新DF2回到原來的DF,但這意味着我必須將列名設置爲一致:

names(DF2) <- c('col1', 'col2') 

確定,現在我可以解決:

rbind(DF2, DF[3,]) 

結果呢?它的工作....

col1 col2 
1 Type 1 3 
3 Type 2 3 

......但唉!太可怕了!必須有更好的方法來簡單地組合值。

回答

2

你可以試試:

library(data.table) 

setDT(transform(DF, col1=gsub("(.*)[A-Z]+$","\\1",DF$col1)))[,list(col2=sum(col2)),col1] 

#  col1 col2 
# 1: Type 1 3 
# 2: Type 2 3 

甚至更​​直接:

setDT(DF)[, .(col2 = sum(col2)), by = .(col1 = sub("[[:alpha:]]+$", "", col1))] 
+0

有一定是做這麼簡單的東西更概括的方式,不是嗎?當然,這樣一個簡單的操作不應該包括正則表達式匹配! –

+0

現在在一行中。但是你需要'gsub'或者找到另一種模式來識別'type 1'和'type1B'類似。彙總可以用'aggregate','dplyr','data.table'等完成。 –

4

這裏有一個可能dplyr方法:

library(dplyr) 
DF %>% 
    group_by(col1 = sub("(.*\\d+).*$", "\\1", col1)) %>% 
    summarise(col2 = sum(col2)) 
#Source: local data frame [2 x 2] 
# 
# col1 col2 
#1 Type 1 3 
#2 Type 2 3 
4

使用sub()aggregate(),removin克任何比從col1端部的其他數字,

do.call("data.frame", 
    aggregate(col2 ~ cbind(col1 = sub("\\D+$", "", col1)), DF, sum) 
) 
#  col1 col2 
# 1 Type 1 3 
# 2 Type 2 3 

do.call()的包裝是有使得aggregate()之後的第一列被適當地從一個矩陣的矢量改變。這樣以後在路上就沒有任何意外了。

1

在我看來,aggregate()是完美的功能,但您不必進行任何文本處理(例如gsub())。我將通過兩步過程完成此操作:

  1. 用新的所需分組覆蓋col1
  2. 使用新的col1來計算聚合以指定分組。

DF$col1 <- ifelse(DF$col1 %in% c('Type 1','Type 1B'),'Type 1',levels(DF$col1)); 
DF; 
##  col1 col2 
## 1 Type 1 1 
## 2 Type 1 2 
## 3 Type 2 3 
DF <- aggregate(col2~col1, DF, FUN=sum); 
DF; 
##  col1 col2 
## 1 Type 1 3 
## 2 Type 2 3 
+0

我認爲這是最好的答案,因爲它避免了與文本混搭。它保持低複雜性。 –