2016-01-23 73 views
3

我想這可能是一個簡單的技巧,但我不知道該如何實現呢?結合STARTS_WITH與GROUP_BY在dplyr

我dateset樣子:

Name, Score 
A a, 20 
A, 30 
B b, 40 

我期望的輸出是:

Name, Score 
A, 50 
B, 40 

總之,總結名稱以相同單詞開始的分數(在空格之前,如果有的話)。我希望這個例子是不言自明的。 :)

PS:代碼運行得越快,效果越好。該數據集是巨大的......

+2

在基礎R相當簡單'骨料(分數〜cbind(名稱=子( 「*」, 「」,名稱) ),df,sum)' –

回答

1

另一種選擇是separate

library(dplyr) 
library(tidyr) 
separate(df1, Name, into=c("Name", "extra")) %>% 
     group_by(Name) %>% 
     summarise(Score=sum(Score)) 
#  Name Score 
# (chr) (int) 
#1  A 50 
#2  B 40 

或者extract

extract(df1, Name, into= "Name", "(\\S+).*") %>% 
      group_by(Name) %>% 
      summarise(Score = sum(Score)) 
+1

謝謝你指點我到tidyr圖書館。事實證明,這非常方便。 –

2

你可以嘗試這樣的事情:

library(dplyr) 
library(stringr) 

df$newName <- str_extract(df$Name, '[[:alnum:]]+') 
df %>% group_by(newName) %>% summarise(Score = sum(Score)) 

Source: local data frame [2 x 2] 

    newName Score 
    (chr) (int) 
1  A 50 
2  B 40 

注意,你會希望確保「名稱」讀爲特徵向量,而不是作爲因素。在您的閱讀電話中使用stringsAsFactors = FALSE,或使用as.character將其轉換。在COLUMNNAMES不是在列中的值

df$newName <- str_extract(df$Name, '([^\\s]+)') 
2

starts_withselectrename使用,並且操作:

如果你想充分第一「串」,你也可以用這個正則表達式。通過使用gsub,您可以提取第一個字母(或單詞),然後進行總結。附:

sumdf <- mydf %>% 
    group_by(Name = gsub("[^A-Za-z0-9].*", "", Name)) %>% 
    summarise(sumScore = sum(Score)) 

你:

> sumdf 
    Name sumScore 
1  A  50 
2  B  40 
1

我以前substr提取的第一個字母,然後group_by。我相信dplyr starts_with被用來根據他們的標題來選擇整個列。此解決方案僅適用於您要選擇的字母始終是第一個字母的情況。

require(dplyr) 
df<-data.frame(Name=c("A a,","A,","B b"),Score=c(20,30,40)) 

df$Name <- substr(df$Name,1,1) 
df %>% group_by(Name) %>% summarise(sum_score=sum(Score)) 

Source: local data frame [2 x 2] 

    Name sum_score 
    (chr)  (dbl) 
1  A  50 
2  B  40 

你也可以,如果你想保持原來的數據,因爲它是創建子列作爲新列和組通過。