からっぽのしょこ

読んだら書く!書いたら読む!同じ事は二度調べ(たく)ない

R言語でツイート数の推移をグラフにする

はじめに

 rtweetパッケージを利用して指定したアカウントのタイムラインを収集し、設定した期間ごとにツイート数を集計し、ツイート数を棒グラフによって可視化します。

f:id:anemptyarchive:20200525102411p:plain
ツイート数(日別)


・ツイート数を棒グラフで可視化

 rtweetパッケージを利用して、指定したアカウントのタイムラインインを収集し、設定した期間(年・月・日・時)ごとのツイート数を集計し、棒グラフを作図します。

library(rtweet) # ツイート収集:get_timeline(), search_tweets()
library(dplyr) # データフレーム操作
library(lubridate) # 時間データ操作:floor_date(), as_date()
library(ggplot2) # 作図

 利用するパッケージを読み込みます。

・ツイート収集

 まずはrtweetパッケージを利用して、ツイートを集めます。

# アカウントを指定
screen_name <- "anemptyarchive"

# アカウント指定でツイートを収集
tw_data <- get_timeline(screen_name, n = 10000, include_rts = FALSE)

 get_timeline()の第1引数にアカウント(@○○○の○○○)を指定して、ツイートを取得します。引数nは収集するツイート数、include_rtsは取得ツイートにリツイートを含めるかです(デフォルトはTRUE)。

 特定の単語を含むツイートを収集するのであれば、search_tweets("検索ワード")を使います。

 取得できるツイートの数に制限があったりします。

 ツイート日時の情報があればいいので、取得したツイートデータのうちcreated_at列のみを使います。それではcreated_at列のデータを確認してみましょう。

tw_data[["created_at"]][1:10]
##  [1] "2020-05-24 15:48:56 UTC" "2020-05-24 01:33:57 UTC"
##  [3] "2020-05-23 14:55:20 UTC" "2020-05-23 14:45:54 UTC"
##  [5] "2020-05-23 14:35:50 UTC" "2020-05-23 14:15:49 UTC"
##  [7] "2020-05-23 14:12:26 UTC" "2020-05-23 13:59:04 UTC"
##  [9] "2020-05-23 10:33:35 UTC" "2020-05-23 10:26:21 UTC"

 取得したツイート日時のタイムゾーンが協定世界時(UTC)です。これを日本標準時(JST)に変換にする必要があります。

# ツイート日時データを変換
tw_time <- tw_data[["created_at"]] %>% # ツイート日時を抽出
  as.POSIXct(tz = "Etc/GMT") %>% # POSIXct型の協定世界時を明示
  as.POSIXlt(tz = "Asia/Tokyo") # POSIXlt型の日本標準時に変換

 as.POSIXlt()でPOSIXct型からPOSIXlt型に変換します。またtz引数に"Japan"あるいは"Asia/Tokyo"を指定して、タイムゾーンを日本標準時に変更します。(多分2行目はいらない)

 変換後のデータを確認しておきましょう。

tw_time[1:10]
##  [1] "2020-05-25 00:48:56 JST" "2020-05-24 10:33:57 JST"
##  [3] "2020-05-23 23:55:20 JST" "2020-05-23 23:45:54 JST"
##  [5] "2020-05-23 23:35:50 JST" "2020-05-23 23:15:49 JST"
##  [7] "2020-05-23 23:12:26 JST" "2020-05-23 22:59:04 JST"
##  [9] "2020-05-23 19:33:35 JST" "2020-05-23 19:26:21 JST"

 これでツイートデータの取得と前処理は完了です。次からは可視化のための処理を行っていきます。

・年・月・日別に可視化

 ここからは、指定した期間(年・月・日)ごとにツイート数を集計し、棒グラフを作図していきます。

# セルの単位(区切る期間)を指定
term <- "year"
term <- "mon"
term <- "day"

 ツイート数をカウントする際に区切る間隔を指定します。「年」単位であればyear、「月」単位ならmon、「日」単位ならdayとします。これは主にfloor_date()unit引数に指定するためのものなので、このままの文字列を使用してください。

 指定した期間ごとのツイートを数を集計します。

# 指定した期間ごとにツイート数を集計
tw_count <- tw_time %>% 
  floor_date(unit = term) %>% # 指定した単位に切り捨て
  as_date() %>% # Date型に変換
  tibble(terms = .) %>% # データフレームに変換
  count(terms) # ツイート数をカウント

 floor_date()で指定した期間ごとに日時を丸め(切り捨て)ます。
 また時刻情報も不要なので、as_date()でPOSIXlt型からDate型に変換することで落とします。
 次にtibble()でデータフレームに変換して、count()で各期間のツイート数を集計します。

tail(tw_count, 10)
## # A tibble: 10 x 2
##    terms          n
##    <date>     <int>
##  1 2020-05-15     5
##  2 2020-05-16     3
##  3 2020-05-18     2
##  4 2020-05-19     7
##  5 2020-05-20     4
##  6 2020-05-21     4
##  7 2020-05-22     8
##  8 2020-05-23    20
##  9 2020-05-24     1
## 10 2020-05-25     1

 このデータフレームを用いて作図します。作図の処理は指定した期間によって異なるため、場合分けしておきます。

# 棒グラフを作図
if(term == "day") {
  
  ggplot(tw_count, aes(x = terms, y = n)) + 
    geom_bar(stat = "identity", fill = "#00A968") + # 棒グラフ
    scale_x_date(date_breaks = "2 weeks", date_labels = "%Y-%m-%d") + # x軸目盛(日付)
    theme(axis.text.x = element_text(angle = 90)) + # x軸目盛の傾き
    labs(title = paste0("@", screen_name, "のツイート数"), 
         x = "year-mon-day") # ラベル
  
} else if(term == "mon") {
  
  ggplot(tw_count, aes(x = terms, y = n)) + 
    geom_bar(stat = "identity", fill = "#00A968") + # 棒グラフ
    scale_x_date(date_breaks  = "1 month", date_labels = "%Y-%m") + # x軸目盛(日付)
    theme(axis.text.x = element_text(angle = 90)) + # x軸目盛の傾き
    labs(title = paste0("@", screen_name, "のツイート数"), 
         x = "year-mon") # ラベル
  
} else if(term == "year") {
  
  ggplot(tw_count, aes(x = terms, y = n)) + 
    geom_bar(stat = "identity", fill = "#00A968") + # 棒グラフ
    scale_x_date(date_breaks = "1 year", date_labels = "%Y") + # x軸目盛(日付)
    labs(title = paste0("@", screen_name, "のツイート数"), 
         x = "year") # ラベル
  
}

 geom_bar()で棒グラフを作図します。

 x軸に表示するデータ数が多くなるため、必要に応じてx軸目盛を表示する位置を間引きます。
 Date型のデータの場合は、scale_x_date()でx軸目盛を調整できます。date_breaks引数に表示する位置を、date_labels引数に表示するテキストの形式を指定します。

f:id:anemptyarchive:20200525102411p:plain
ツイート数:日別

f:id:anemptyarchive:20200525100324p:plain
ツイート数:月別

f:id:anemptyarchive:20200525100344p:plain
ツイート数:年別

・時別に可視化

 続いて、1時間ごとにツイート数を棒グラフ化します。
 基本的な処理は同じです。こちらは可視化に時刻データを用いるため、ツイート日時をPOSIXct型で扱うところが異なります。

# セルの単位(区切る期間)を指定
term <- "hour"

 区分けするときに用いる変数を"hour"としておきます。

# 指定した期間ごとにツイート数を集計
tw_count <- tw_time %>% 
  floor_date(unit = term) %>% # 指定した単位に切り捨て
  as.POSIXct() %>% # POSIXct型に変換
  tibble(terms = .) %>% # データフレームに変換
  count(terms) %>% # ツイート数をカウント
  filter(terms >= as.POSIXct("2020-01-01")) %>% # から
  filter(terms <= as.POSIXct("2020-01-31")) # まで

 floor_date(., unit = "hour")で1時間単位で丸めて(切り捨て)、as.POSIXct()でPOSIXct型に戻します。
 またtibble()でデータフレームに変換して、count()で各期間のツイート数を集計します。
 描画するデータ量が多くなると思われるので、描画する範囲を絞っておきます。

 完成したデータフレームを確認しておきましょう。

tail(tw_count, 10)
## # A tibble: 10 x 2
##    terms                   n
##    <dttm>              <int>
##  1 2020-01-25 12:00:00     5
##  2 2020-01-25 18:00:00     2
##  3 2020-01-26 17:00:00     1
##  4 2020-01-26 19:00:00     1
##  5 2020-01-27 14:00:00     1
##  6 2020-01-27 16:00:00     1
##  7 2020-01-27 18:00:00     1
##  8 2020-01-27 19:00:00     1
##  9 2020-01-28 12:00:00     1
## 10 2020-01-28 23:00:00     1

 これを用いて作図します。

# 棒グラフを作図
ggplot(tw_count, aes(x = terms, y = n)) + 
  geom_bar(stat = "identity", fill = "#00A968") + # 棒グラフ
  scale_x_datetime(date_breaks = "12 hours", 
                   date_labels = "%Y-%m-%d %H") + # x軸目盛(日時)
  theme(axis.text.x = element_text(angle = 90)) + # x軸目盛の傾き
  labs(title = paste0("@", screen_name, "のツイート数"), 
       x = "year-mon-day hour") # ラベル

 POSIXct型のデータのときは、scale_x_datetime()でx軸目盛を調整できます。引数はscale_x_date()と同じく、date_breaks引数に表示する位置、date_labels引数に表示するテキストの形式を指定します。

f:id:anemptyarchive:20200525102743p:plain
ツイート数:時別

以上です!

おわりに

 えーと週単位は忘れてました。気付いたものの、ちょっとこのままのコードじゃ対応できないだろうなと思ったり。その内付け足しておきます。それと棒グラフだと案外分かり難かったので、次はヒートマップでも可視化したいです。

www.anarchive-beta.com

 そもそもこれは、任意の期間ごとにツイートテキストをまとめて、ネガポジ分析をするための過程の作業のようなものです。なので早くそれもしてみたい。

www.anarchive-beta.com

 今まで統計分析をしてなかったので、基本的なグラフの類は使ってませんでした。使うことがあってもbarplot()でしてました。でも格好良く可視化してみたかったので、今回初めてggplot2を使ってみました。雰囲気は分かったものの、まだ使いこなせていないのでもっと練習せねば。

 最後までありがとうございました。次もよろしくお願いします。前記事が初日で100アクセス超えました。 R言語でトピックモデルとクラスタリング - からっぽのしょこ

 ありがとうございます!!!

2020/05/25:全文書き直しました。

 日時データを文字列型に変換せずに、Date型やPOSIXlt型として扱い作図できるようになりました。元々は正規表現を使って目盛の表示の調整なぞしておりました。日時データじゃないと表示の調整等をうまいことしてくれないので、色々と追加の処理が必要でした(その片鱗はヒートマップの方に少し残ってます)。それで週別版をすぐにできなかったわけです(というか1週間ごとの可視化もしたかったのか…今修正が終わってあとがきを追加するまで忘れてました。なので今回も未対応です!が、特に追加的な処理は必要なくterm <- "week"としたらできるんじゃないかな)。