ESDちゃんのRT & Fav

冬コミの原稿でRを全く触らなかった(グラフはRで書いたけど)のでリハビリも兼ねてESDちゃんのtwitterからメンバーごとのRTとFavの統計を求めることにした。

https://twitter.com/earthstar_dream

今現在350くらいしかpostしてないので簡単に全部のログを取ってこれる。

とりあえずこんな感じの入力ファイルを作る。

$ cut -c -70 esd_rtfav.txt | head -5
name    rt      fav     id      text
谷尻まりあ      3       5       555225418421112833      こんにちは。青の谷尻まりあです。「声
中島由貴        3       12      555129738151219200      アーススタードリーム中島由貴です?おは
曽我部英理      2       8       555025061426368512      こんばんは!オレンジの曽我部英理です
小出ひかる      2       12      555021299517374467      こんばんは?(*∩ω∩*)黄色の小出ひか

データはgithubにアップロードしようかと思ったけどgoogleでいいわ。

https://docs.google.com/spreadsheets/d/1b6mMbliVOAwspOO5dtCwdrWyzwknD8nCN5WI_x9GlDk/export?format=tsv

で、ggplot2でグラフにする。

library(ggplot2)
library(reshape2)
library(plyr)

# データ読み込み
d <- read.delim("esd_rtfav.txt", colClasses=c("character", "numeric", "numeric", "character", "character"))

# その他(運営とか)のpostを除外
d2 <- d[d[,1] != "その他",]

# ggplot2用にデータを加工
d.m <- melt(d2[,1:3])

# favのmedian順でfactorをソート
d.m[,1] <- factor(d.m[,1], levels=names(sort(tapply(d2[,3], factor(d2[,1]), median), dec=T)), ordered=T)

# plot
p <- ggplot(data=d.m, aes(x=name, y=value)) + geom_boxplot(aes(colour=variable), outlier.shape=NA) + theme(axis.text.x=element_text(angle=90)) + scale_y_continuous(limits=quantile(d.m$value, c(0, 0.9)))
ggsave(file="esd.png", plot=p)

# 参考1:最大RT/fav
ldply(by(d2, factor(d2[,1]), function(x){x[which.max(x$rt),]}))
ldply(by(d2, factor(d2[,1]), function(x){x[which.max(x$fav),]}))

# 参考2:post数
data.frame(count=sort(tapply(d2[,1], factor(d2[,1]), length), dec=T))

こんな短いコードで書けて便利だね!でもコードの書き方調べるのに5時間くらい掛かってるからExcelでやったほうが早いね!

fav数の中央値でx軸ソートしたけど、これを見るとゆっきーさおりん辺りが人気なのかなあ。さおりんは自撮りカワイイからね!

いづみんこと新井田いづみちゃん、favはそれほどでも無いけどRTが多い。スパルタンMXに出ていたようなので、その辺の身内関連なのかも。調べてないけど。

とは言え、こうして見ると多少の上下はあるものの、それほどRTやfavに格差が出てるわけでは無さそう。今のところは中島由貴ちゃんが比較的推されてる感あるけど、まだまだ横並びな感じですね。

個別のtwitterアカウントができればもう少し格差が広がっていくことになるのかなあ。社長の方針としては、まだ個別アカウントは作らないみたいなので、もうしばらく様子を見守ろう。

post数の統計

名前 post数
中島由貴 51
小出ひかる 38
斎藤愛永 33
谷尻まりあ 33
高尾奏音 32
愛原ありさ 30
村北沙織 27
新井田いづみ 26
曽我部英理 21

なるほど。

最大RT/favを達成したpostも調べたけど、「はじめまして」postがほとんどであんまり面白くない。

RT

愛原ありさ (30 RT)

高尾奏音 (25 RT) 斎藤愛永 (18 RT) 小出ひかる (35 RT)新井田いづみ (19 RT) 曽我部英理 (17 RT) 村北沙織 (14 RT) 谷尻まりあ (20 RT) 中島由貴 (32 RT)

fav

愛原ありさ (42 fav)

高尾奏音 (24 fav) 斎藤愛永 (24 fav) 小出ひかる (35 fav)新井田いづみ (23 fav) 曽我部英理 (33 fav) 村北沙織 (26 fav) 谷尻まりあ (24 fav) 中島由貴 (38 fav)

データ取得用コード

本文に名前か担当色が入っているかどうかで名前の判別をしている。

一番先にキーワードが出てきた人が投稿者だろうと仮定しているけど、ときどき誤検知をするので最終的には手動でチェックしないといかん。

use strict;
use warnings;
use Net::Twitter;
use Scalar::Util qw/blessed/;
use Getopt::Std;
use Encode;
use List::Util qw/reduce/;
use utf8;
binmode STDIN,  ":utf8";
binmode STDOUT, ":utf8";
binmode STDERR, ":utf8";

my $opt = {};
getopts("n:p:c:", $opt);

my $name_table = {
  中島由貴     => '中島由貴|ゆっきー|白',
  高尾奏音     => '高尾奏音|のんのん|ピンク',
  小出ひかる   => '小出ひかる|ひかるん|黄色',
  斎藤愛永     => '斎藤愛永|ぴぃちゃん|水色',
  愛原ありさ   => '愛原ありさ|あーりぃ|赤',
  曽我部英理   => '曽我部英理|えりりん|オレンジ',
  谷尻まりあ   => '谷尻まりあ|まりあんぬ|青',
  新井田いづみ => '新井田いづみ|いづみん|黄緑',
  村北沙織     => '村北沙織|紫',
};

my $screen_name = $opt->{n} || 'earthstar_dream';
my $page        = $opt->{p} || 1;
my $count       = $opt->{c} || 20;

my $nt = Net::Twitter->new(
  traits   => [qw/API::RESTv1_1/],
  consumer_key        => $consumer_key       ,
  consumer_secret     => $consumer_secret    ,
  access_token        => $access_token       ,
  access_token_secret => $access_token_secret,
);

my $statuses = [];

while(1){
  print STDERR "getting page $page..\n";
  
  eval{
    $statuses = $nt->user_timeline({screen_name=>$screen_name, page=>$page, count=>$count});
    ### $statuses
  };
  if(my $err = $@){
    ### $err
    if(blessed $err && $err->isa('Net::Twitter::Error')){
      warn $err->error;
    }
    else {
      # something bad happened!
      die $err;
    }
  }
  last unless @$statuses;
  print_status($statuses);
  $page++;
  sleep 1;
}

sub print_status{
  my $st = shift;
  foreach my $e (@$st){
    # determine a name : check the first matched position, and choose the leftmost person
    my $text = $e->{text}; $text =~ tr/\x0A\x0D//d;
    my %l = map { $text =~ /$name_table->{$_}/; (@- ? ($_ => $-[0]) : ()) } keys %$name_table;
    my $n = (%l ? (reduce { $l{$a} < $l{$b} ? $a : $b } keys %l) : 'その他');
    printf("%s\t%d\t%d\t%s\t%s\n", $n, $e->{retweet_count}, $e->{favorite_count}, $e->{id}, $text);
  }
}