2016-01-23 112 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 

你也可以,如果你想保持原来的数据,因为它是创建子列作为新列和组通过。