這裡介紹 R 的 Rfacebook 套件使用方式,並提供各種 Facebook 社群網路資料分析的參考範例。

Facebook 是全球知名的社群網站,上面有非常大量的社群網路資料,當然也蘊藏了龐大的商機,如何分析 facebook 的資料、從中萃取有用的資訊,已經成為現在很熱門的領域之一。

分析 facebook 的資料,除了一般的統計工具之外,還需要結合 Facebook Graph API 來擷取資料,很慶幸的是 R 官方收錄的 Rfacebook 已經將這些功能都已經整合好了,以下我們將介紹如何安裝以及使用這個套件,分析出各種有用的社群資訊。

取得 Facebook 權限認證

在使用 Facebook Graph API 之前,我們必須先取得 facebook 的權限認證,經過認證之後,才能從 facebook 網站上擷取資料。

facebook 提供的認證方式有兩種,一種是使用 facebook app 的方式,另一種則是直接產生一個暫時的存取權杖(token),不管使用那一種都可以。

建立 Facebook App

以下是建立一個 facebook app 的操作步驟。

Step 1

開啟 facebook for developers 的網頁,點選「新增應用程式」。

新增應用程式

Step 2

選擇「網站」這個平台。

選擇「網站」

Step 3

輸入 App 的名稱,這裡任意取一個名稱即可。

輸入 App 的名稱

Step 4

輸入聯絡用的電子郵件信箱。

輸入電子郵件信箱

Step 5

點選右上角的「Skip Quick Start」。

點選右上角的「Skip Quick Start」

Step 6

點選應用程式密鑰的「顯示」按鈕。

點選應用程式密鑰「顯示」按鈕

Step 7

複製應用程式的編號與密鑰。

應用程式編號與密鑰

有了應用程式的編號與密鑰,我們就可以使用 Rfacebook 套件透過 Facebook Graph API 來取的 facebook 上的資料了。

取得 Facebook 存取權杖(Token)

除了使用應用程式的編號與密鑰之外,還有另外一種認證方式就是使用 facebook 存取權杖(token),這種方式就不需要建立 facebook app,只要從網頁上產生存取權杖代碼即可使用,不過他的時效只有兩小時,過期後就要重新產生。

Step 1

點選「Get User Access Token」。

點選「Get User Access Token」

Step 2

選擇要開放的權限。

選擇要開放的權限

Step 3

複製產生的存取權杖代碼。

複製產生的存取權杖代碼

安裝 Rfacebook 套件

R 的 Rfacebook 套件安裝方式有兩種,最簡單的方式就是跟一般套件一樣從 R 官方的套件庫下載安裝,不過這種方式所安裝的版本有時候比較舊,若要安裝最新的版本,可以改用直接從 Rfacebook 的 GitHub 網站上下載最新的版本來安裝。

從 CRAN 安裝

若要從 R 官方的 CRAN 網站安裝,就執行:

install.packages("Rfacebook")

從 GitHub 安裝

若要從 GitHub 下載最新版的 Rfacebook,首先需要先安裝 devtools

install.packages("devtools")
library(devtools)

接著使用 install_github 安裝 Rfacebook

install_github("Rfacebook", "pablobarbera", subdir="Rfacebook")
library(Rfacebook)

Rfacebook 認證設定

使用 Facebook 存取權杖(Token)

從 facebook 的 Graph API 測試工具的網頁上產生一個存取權杖(token),將其複製之後,放在 R 的 token 變數中:

token <- "EAACEdEose0cBANAjh3xCYmHWoQPi9MZBZCuIyLBOvsCtH71vTnndd5NsIeSvy5UU1DSSxCYjX8pWIOvRBid6lWOwYwhAxDzZA3dnsbRadtj3FZCaHfpBndc8ae911Wp0pR5GPoq3ZAa5AWooIe34aYkVmkvBHRFt1n44kbWJNywZDZD"

有了存取權杖之後,就可以使用 Rfacebook 來擷取 facebook 網站上的資料了:

me <- getUsers("me", token, private_info = TRUE)
me$name
[1] "Guo-Zhao Wang"

使用 Facebook 應用程式編號與密鑰

使用 fbOAuth 函數,配合上面複製的應用程式編號與密鑰,即可獲取可長期使用的 OAuth 授權 token:

require("Rfacebook")
fb.oauth <- fbOAuth(
  app_id="1675426256053176",
  app_secret="216739d2688d42b4d1d1d901fa4cbbc4",
  extended_permissions = TRUE)
Copy and paste into Site URL on Facebook App Settings: http://localhost:1410/
When done, press any key to continue...

將這裡的網址 http://localhost:1410/ 複製起來,開啟 facebook app 的網頁,在「設定」頁面中,點選「新增平台」。

facebook app 設定

選擇「網站」。

選擇「網站」

將剛剛複製的網址貼在「網站網址」欄位中。

貼上網站網址

按下任意鍵,等待瀏覽器進行認證:

Waiting for authentication in browser...
Press Esc/Ctrl + C to abort
Authentication complete.
Authentication successful.

認證完成後,測試是否可以正常擷取資料:

me <- getUsers("me",token=fb.oauth)
me$name
[1] "Guo-Zhao Wang"

將這個 token 儲存起來,以備未來使用:

save(fb.oauth, file="fb_oauth")

未來在使用前,只要使用 load 載入這個 token 就可以直接使用:

load("fb_oauth")

使用 Rfacebook 套件

Facebook 粉絲專頁

首先複製 facebook 粉絲專頁的 id,而常見的 id 有兩種,一種是純數字的,一種則是使用者自己命名的:

https://www.facebook.com/G-T-Wang-489529864441673/
https://www.facebook.com/humansofnewyork

接著使用 getPage 來取得粉絲專頁上面的文章資訊:

page.id <- "489529864441673" # G.T.Wang 粉絲專頁
page <- getPage(page.id, token, n = 300)
str(page)
'data.frame':	300 obs. of  10 variables:
 $ from_id       : chr  "489529864441673" "489529864441673" "489529864441673" "489529864441673" ...
 $ from_name     : chr  "G. T. Wang" "G. T. Wang" "G. T. Wang" "G. T. Wang" ...
 $ message       : chr  "這裡介紹如何設定標準網址(canonical link),讓自己網站可以在 Google 搜尋結果上呈現正確的網址,達到搜尋引擎最佳化的效果。" "本篇介紹如何改變 WordPress 文字編輯器的字型大小與顏色,讓原始的 HTML 程式碼更容易閱讀。" "一派胡塩酵素臭豆腐新市店是一家靠近南科的素食小吃,臭豆腐外酥內軟,用餐環境整潔衛生。" "Sci-Hub 是一個可以免費下載期刊論文全文電子檔的網站,推倒通往科學道路上的圍籬。" ...
 $ created_time  : chr  "2016-04-27T04:01:45+0000" "2016-04-27T00:25:27+0000" "2016-04-25T07:51:27+0000" "2016-04-24T04:59:53+0000" ...
 $ type          : chr  "link" "link" "link" "link" ...
 $ link          : chr  "http://blog.gtwang.org/web-development/google-canonical-link-setup-after-changing-url/" "http://blog.gtwang.org/wordpress/change-font-and-color-in-text-editor/" "http://blog.gtwang.org/life/yi-pai-hu-yan-stinky-tofu-xinshi-tainan/" "http://blog.gtwang.org/free/sci-hub-download-papers-for-free/" ...
 $ id            : chr  "489529864441673_1054145887980065" "489529864441673_1054059014655419" "489529864441673_1053005288094125" "489529864441673_1052385961489391" ...
 $ likes_count   : num  5 4 2 7 7 3 8 8 3 8 ...
 $ comments_count: num  0 0 1 0 0 0 10 7 4 14 ...
 $ shares_count  : num  0 0 1 0 2 1 0 3 1 1 ...

依據時間畫出網友的迴響數量:

## convert Facebook date format to R date format
format.facebook.date <- function(datestring) {
  date <- as.POSIXct(datestring, format = "%Y-%m-%dT%H:%M:%S+0000", tz = "GMT")
}
# aggregate metric counts over month
aggregate.metric <- function(metric) {
  m <- aggregate(page[[paste0(metric, "_count")]], list(month = page$month),
    mean)
  m$month <- as.Date(paste0(m$month, "-15"))
  m$metric <- metric
  return(m)
}
# create data frame with average metric counts per month
page$datetime <- format.facebook.date(page$created_time)
page$month <- format(page$datetime, "%Y-%m")
df.list <- lapply(c("likes", "comments", "shares"), aggregate.metric)
df <- do.call(rbind, df.list)
# visualize evolution in metric
library(ggplot2)
library(scales)
ggplot(df, aes(x = month, y = x, group = metric)) +
  geom_line(aes(color = metric)) +
  scale_y_log10("Average count per post",
  breaks = c(2, 10, 50, 100)) +
  theme_bw() +
  theme(axis.title.x = element_blank())

這是每篇文章平均的迴響狀況:

facebook-average-count-per-post-1

取出按「讚」數最高的文章:

top.post <- page[which.max(page$likes_count), ]
top.post
from_id  from_name
62 489529864441673 G. T. Wang
                                                                    message
62 Zoolz 的終身 1TB 雲端備份空間現在大特價,只要 $39 美金,比買硬碟還便宜!
               created_time type
62 2016-01-15T23:54:46+0000 link
                                                                                 link
62 http://blog.gtwang.org/funny/get-1tb-zoolz-cold-storage-for-lifetime-subscription/
                                id likes_count comments_count shares_count
62 489529864441673_993084634086191         489              4            9

分析這一篇文章按讚的人:

post <- getPost(top.post$id, token, n = 1000, likes = TRUE, comments = FALSE)
users <- getUsers(post$likes$from_id, token)
head(sort(table(users$last_name), decreasing = TRUE))
陳   林   黃   李 Chen   楊
  42   31   18   17   14   14

畫出前 10 個姓氏:

top.last.name <- head(sort(table(users$last_name), decreasing = TRUE), n = 10)
top.last.name.df <- data.frame(last.name=rownames(top.last.name),
  count = top.last.name)
top.last.name.df$last.name <- reorder(top.last.name.df$last.name, top.last.name.df$count)
ggplot(data = top.last.name.df, aes(x = last.name, y = count)) +
  geom_bar(stat="identity")

facebook-last-name-barplot-1

Facebook 好友

由於 facebook 的 Graph API 在 2.0 版之後,將取得 facebook 好友相關資訊的權限停用了,所以現在我們無法直接使用 Rfacebook 來獲取 facebook 上好友的關係資料,這個問題在 stackoverflow 上也有許多人討論,不過由於這是 facebook 的政策改變所致,所以目前無解。

參考資料