1

次のようなメッセージを表すデータフレームがあるとします。

df <- structure(list(message.id = c(123L, 456L), user.id = c(999L, 888L), 
      message.date = structure(c(1310950467, 1311119810), class = c("POSIXct", 
      "POSIXt"), tzone = "")), .Names = c("messageid", "user.id", 
      "message.date"), row.names = c(NA, -2L), class = "data.frame")

head(df)
message.id   user.id    message.date         
123         999       2011-07-17 17:54:27
456         888       2011-07-19 16:56:50

一部のユーザーが多くのメッセージを持ち、他のユーザーが非常に少ないと仮定して、ユーザーあたりの1日の平均メッセージ数をどのようにプロットしますか(パレート分布など)。

ありがとう。

4

3 に答える 3

3

あなたの例は実際に作業するには非常に小さいので、同じはずのより大きなデータフレームをシミュレートしました:

set.seed(1)
start <- strptime("2012-01-01 00:00:00",format="%Y-%m-%d %H:%M:%S")
end <- strptime("2012-03-01 00:00:00",format="%Y-%m-%d %H:%M:%S")

df <- data.frame(
  message.id = 1:1000,
  user.id = sample(1:10,1000,TRUE,prob=1:10),
  message.date = seq(start,end,length=1000))

次に、最初に日付を (POSIXt ではなく) 日付として抽出する必要があります。

df$date <- as.Date(df$message.date)

plyr次に、次のように、ユーザーごとの 1 日あたりの平均メッセージ数を計算するために使用できると思います。

library("plyr")
df2 <- ddply(df,.(user.id),summarize,AvPerDay = mean(sapply(seq(min(df$date),max(df$date),by="day"),function(x)sum(date==x))))

新しいデータフレームdf2は私に与えます:

   user.id  AvPerDay
1        1 0.3278689
2        2 0.6229508
3        3 0.9836066
4        4 1.1311475
5        5 1.3442623
6        6 1.8524590
7        7 1.8032787
8        8 2.8032787
9        9 2.5081967
10      10 3.0163934

それをプロットするには、棒グラフを作成するだけです:

barplot(df2$user.id,df2$AvPerDay)
于 2012-04-22T16:37:46.120 に答える
1

Sacha の方が優れていますが、彼の回答を見たとき、私は終わったばかりでした。考えられる基本的なアプローチは次のとおりです。

#Make my own data
set.seed(15)
df <- data.frame(messageid= sample(1:1000, 1000), user.id = 
    rep(901:925, each=40), message.date = sample(seq(Sys.time(), 
    length.out = 10000, by = "hours"), 1000, replace=T))

#Make a date column
df$date <- unlist(strsplit(as.character(df$message.date), " "))[c(T, F)]

#split on user id
pidLIST <- split(df, df[, 'user.id'])
#sum and get an average by date
df2 <- data.frame(user.id=as.factor(names(pidLIST)), 
    aveMESS = sapply(seq_along(pidLIST), 
    function(i) mean(aggregate(user.id~date, pidLIST[[i]], length)[, 2])))

plot(df2)

ご存知のように、私は日付を扱うことはあまりありません。

PS 作業するのに十分な大きさの場合、最小限の再現可能な例を提供すると役立ちます。Sacha も私も、独自のデータ セットを再作成する必要がありました。

于 2012-04-22T16:42:57.463 に答える
0

別のアプローチを試みて、次のプロットを試しました。ユーザー メッセージ数の分布を示す毎日の箱ひげ図と、ユーザーあたりの平均メッセージ数を結ぶ線です。ターゲットプロットは次のとおりです。

1 日あたりのユーザー メッセージの分布と平均

@Sacha Epskamp の方法を使用してデータを生成することから始めます。意図したプロットのために何かを得るために、大きなデータセットを生成します

library("ggplot2")
library("lubridate")


# This code from Sacha Eskamp
# http://stackoverflow.com/a/10269840/1290420

# Generate a data set
set.seed(1)
start <- strptime("2012-01-05 00:00:00",
                  format="%Y-%m-%d %H:%M:%S")
end <- strptime("2012-03-05 00:00:00",
                format="%Y-%m-%d %H:%M:%S")

df <- data.frame(message.id = 1:10000,
                 user.id = sample(1:30,10000,
                                 TRUE,
                                 prob=1:30),
                 message.date = seq(start,
                                   end,
                                   length=10000)
                 )

次に、データフレームをプロットに適した形状にするのに苦労します。plyr教祖はこれを大幅に改善できると確信しています。

# Clean up the data frame and add a column 
# with combined day-user
df$day <- yday(df$message.date)
df <- df[ df$day!=65, c(2,4) ]
df$day.user <- paste(df$day, df$user.id, sep="-")

# Copy into new data frame with counts for each
# day-user combination
df2 <- aggregate(df, 
                 by=list(df$day, 
                         df$day.user), 
                 FUN="length"
                 )
df2 <- df2[,c(1,2,3)]
names(df2) <- c("day", "user", "count")
df2$user <- gsub(".+-(.+)", "\\1", df2$user)

次に、プロットを描くのは簡単な部分です。

p <- ggplot(df2,
            aes(x=day,
                y=count))
p <- p + geom_boxplot(aes(group=day), colour="grey80")
p <- p + stat_summary(fun.y=mean, 
                      colour="steelblue", 
                      geom="line",
                      size=1)
p <- p + stat_summary(fun.y=mean, 
                      colour="red", 
                      geom="point",
                      size=3)
p
于 2012-04-23T16:47:21.953 に答える