dplyr? - 寻找一种更有效的方法来汇总数据
dplyr? - looking for a more efficient way to summarise data
又卡住了,希望有更多线索的可以指点一下;o)
我有一个数据集; 3,270 行发布日期 (2013-04-01:2014-03-31) 和域(coindesk、forbes、mashable、nytimes、reuters、techcrunch、thenextweb 和 theverge)。副本为here)
> df <- read.csv("dplyr_summary_example.csv")
> head(df)
datePublished domain
1 2013-04-01 coindesk
2 2013-04-01 coindesk
3 2013-04-13 coindesk
4 2013-04-15 coindesk
5 2013-04-15 coindesk
基本上 df 每次发布一个故事时都会有一行 date/domain 对。
我想做的是创建一个看起来有点像的新数据框(例如,数字是编造的)...
datePublished coindeskStories forbesStories... thevergeStories totalStories
2013-04-01 2 1 1 4
2013-04-13 1 1 0 2
2013-04-15 2 0 1 3
所以对于 df 中的每个日期,我想要一列每个域的总故事,最后是总计列(总计总计很容易)。
我一直在研究 dplyr
,它看起来确实可以完成这项工作,但到目前为止我还没有一步完成。
对于每个域然后加入东西是相当简单的:
daily <- group_by(df,datePublished) # group stories by date
cnt.nytimes <- filter(daily, domain=="nytimes") # filter just the nytimes ones
cnt.nytimes <- summarise(cnt.nytimes,nytimesStories=n()) # give table of stories by date
cnt.mashable <- filter(daily, domain=="mashable")
cnt.mashable <- summarise(cnt.mashable,mashableStories=n())
df.Stories <- full_join(cnt.nytimes,cnt.mashable,by="datePublished") # join cnt. dataframes by datePublished
df.Stories <- arrange(df.Stories,datePublished) #sort by datePublished
df.Stories$totalStories <- apply(df.Stories[c(2:3)],1,sum,na.rm=TRUE) #add a totals column
BUT 在每个域上执行此操作然后使用连接似乎有点低效。
谁能推荐一条更简单的路线?
那reshape2::dcast
呢
require(reshape2)
res <- dcast(df, datePublished ~ domain, value.var = "domain", fun.aggregate = length)
结果:
> head(res)
datePublished coindesk forbes mashable nytimes reuters techcrunch thenextweb theverge
1 2013-04-01 2 2 0 0 0 1 0 2
2 2013-04-02 0 1 1 0 0 0 0 0
3 2013-04-03 0 3 1 0 0 2 0 0
4 2013-04-04 0 0 0 0 0 1 1 1
5 2013-04-05 0 1 0 0 0 1 1 1
6 2013-04-07 0 1 0 1 0 1 0 0
评论:如果您希望将发布日期作为日期而不是因素使用
df$datePublished <- as.Date(as.character(df$datePublished))
紧接着 read.csv
要更改为宽格式,除了 dplyr
之外,您还需要使用 tidyr
。像
library(dplyr)
library(tidyr)
df %>%
group_by(datePublished, domain) %>%
summarise(nstories = n()) %>%
spread(domain, nstories)
为什么不直接使用 ?aggregate
和 ?summary
?
我无法下载您的数据。然而,这可能对您有所帮助:
set.seed(12)
n <- 10000
date <- sample(1:100, n, replace=T)
type <- sample(letters[1:5], n, replace=T)
sample <- data.frame(date=date, type=type)
temp <- sample[date==1,]
aggregate(type ~ date, data=sample, FUN=summary)
又卡住了,希望有更多线索的可以指点一下;o)
我有一个数据集; 3,270 行发布日期 (2013-04-01:2014-03-31) 和域(coindesk、forbes、mashable、nytimes、reuters、techcrunch、thenextweb 和 theverge)。副本为here)
> df <- read.csv("dplyr_summary_example.csv")
> head(df)
datePublished domain
1 2013-04-01 coindesk
2 2013-04-01 coindesk
3 2013-04-13 coindesk
4 2013-04-15 coindesk
5 2013-04-15 coindesk
基本上 df 每次发布一个故事时都会有一行 date/domain 对。
我想做的是创建一个看起来有点像的新数据框(例如,数字是编造的)...
datePublished coindeskStories forbesStories... thevergeStories totalStories
2013-04-01 2 1 1 4
2013-04-13 1 1 0 2
2013-04-15 2 0 1 3
所以对于 df 中的每个日期,我想要一列每个域的总故事,最后是总计列(总计总计很容易)。
我一直在研究 dplyr
,它看起来确实可以完成这项工作,但到目前为止我还没有一步完成。
对于每个域然后加入东西是相当简单的:
daily <- group_by(df,datePublished) # group stories by date
cnt.nytimes <- filter(daily, domain=="nytimes") # filter just the nytimes ones
cnt.nytimes <- summarise(cnt.nytimes,nytimesStories=n()) # give table of stories by date
cnt.mashable <- filter(daily, domain=="mashable")
cnt.mashable <- summarise(cnt.mashable,mashableStories=n())
df.Stories <- full_join(cnt.nytimes,cnt.mashable,by="datePublished") # join cnt. dataframes by datePublished
df.Stories <- arrange(df.Stories,datePublished) #sort by datePublished
df.Stories$totalStories <- apply(df.Stories[c(2:3)],1,sum,na.rm=TRUE) #add a totals column
BUT 在每个域上执行此操作然后使用连接似乎有点低效。
谁能推荐一条更简单的路线?
那reshape2::dcast
require(reshape2)
res <- dcast(df, datePublished ~ domain, value.var = "domain", fun.aggregate = length)
结果:
> head(res)
datePublished coindesk forbes mashable nytimes reuters techcrunch thenextweb theverge
1 2013-04-01 2 2 0 0 0 1 0 2
2 2013-04-02 0 1 1 0 0 0 0 0
3 2013-04-03 0 3 1 0 0 2 0 0
4 2013-04-04 0 0 0 0 0 1 1 1
5 2013-04-05 0 1 0 0 0 1 1 1
6 2013-04-07 0 1 0 1 0 1 0 0
评论:如果您希望将发布日期作为日期而不是因素使用
df$datePublished <- as.Date(as.character(df$datePublished))
紧接着 read.csv
要更改为宽格式,除了 dplyr
之外,您还需要使用 tidyr
。像
library(dplyr)
library(tidyr)
df %>%
group_by(datePublished, domain) %>%
summarise(nstories = n()) %>%
spread(domain, nstories)
为什么不直接使用 ?aggregate
和 ?summary
?
我无法下载您的数据。然而,这可能对您有所帮助:
set.seed(12)
n <- 10000
date <- sample(1:100, n, replace=T)
type <- sample(letters[1:5], n, replace=T)
sample <- data.frame(date=date, type=type)
temp <- sample[date==1,]
aggregate(type ~ date, data=sample, FUN=summary)