見出し画像

【R/Shiny】冬休みの工作「ツイート収集webアプリ」を作る

●やること

本記事ではRとshiny、Twitter API keyを使ってツイートを収集するwebアプリを無料で作ります。

For English speakers.
In this article, I will create a free web application that collects tweets using R, shiny, and Twitter API key.
The program code is in English only, but the text is in Japanese, so please use a translation site to read it.
If you want to contact me, you can DM me on Twitter in English.

●前書き

Twitter便利ですよね。

SNSマーケティングしたり、検索して楽しい人を探したり…。
でも、検索しても引っかからない人がいたり、検索結果から良いツイートを探すのが面倒だったりです。
エゴサする方も多いですが、探したいツイートを探せなくて大変。
リツイート順やフォロワー数順に並べたり、検索結果をエクセルファイルでダウンロードしたり、シャドウバンされてる人も検索できるツールが欲しい…
なんて思いませんか?
でもTwitterを収集するWEB上のツールはかゆいところに手が届かないし、業者に制作を外注すると何十万と取られてしまう…。

そういう時は、そう。

作ればよい。

という訳で本記事ではChromeやFirefox上で動作する、↓のようなTwitterのWebアプリをRで作っていきます。

動作中のwebアプリ

主な機能は以下のような感じです。
・15分間あたり18,000ツイートの収集が可能
 (過去7日間まで)
・収集したツイートは表形式で表示され、リツイート数やフォロワー数でソート可能
・収集したツイートをエクセルファイルでダウンロードできる
・PC/スマホのChromeやFirefox、Safariなどのブラウザで動作する
・ログインフォーム付きで決められた人だけ使用可能
・カスタマイズ可能(要プログラミング知識)

これが作れれば君も最強のエゴサーチャー、界隈ウォッチャー、Twitterの分析者、SNSマーケティングリサーチャーになれる!
なりなよ!
なれ!!!
ネットに繋がったPCがあればできますので、お子様の冬休みの工作にもぴったりですね。
お子様がTwitterを見るのは気を付けた方が良いですが…。

●必要な物

なんとPCがあれば無料でできます。
・インターネットに接続されたパソコン
 本記事ではWindows10環境です。
・ファイルパスや拡張子変更等のパソコンの知識
・R(無料)
・Rstudio(無料)
・Twitterのアカウント(無料)
・Twitter開発者アカウント(無料)
・Shinyappsのアカウント(無料)
・所要時間30分~300分(PCスキルと環境運による)

途中でエラーが起こるなど分からないことがあればTwitterのDMにお問い合わせいただければお答えできる…かも。

●作る前に…

主にRのプログラム周りを解説します。
Rのインストール方法やTwitter開発者アカウントの取得方法は別サイトに丸投げします。

・RとRstudioをインストールする

「R Rstudio インストール方法」で検索するか、上記ページをご参考ください。
Windows10環境でユーザーが名がマルチバイト文字の場合、RやRstudioをデフォルトの場所にインストールすると下のステップ─特にshinyappsへのアップロード─がうまくいきません。
onedriveの中にインストールするのもエラーの原因となります。

Cドライブ直下にインストールするなどマルチバイトが含まれないフォルダにインストールしましょう。

・Twitter開発者アカウントとAPI keyを取得する

Twitter developerからTwitter開発者アカウントとAPI keyを取得します。

https://developer.twitter.com/en

Twitter取得用ページの内容はコロコロ変わりますので「twitter API key 取得」で検索して最新情報をご参考ください。
質問はDeepL翻訳で訳しつつ、入力する内容も日本語からDeepLで英訳して入力すればOKです。

https://www.deepl.com/ja/translator

必要なのは以下の5つなのでメモしておいてください。
─設定したアプリ名
─Consumer API key
─Consumer Secret
─Access Token
─Access Secret

設定したappはUser authentication settingsApp permissionsでReadにしておくと安心です。

Read and writeだと万一のAPI流出時にえらいことになりそうなので…

●作り方

・API keyのjsonファイルを作る

API keyはTwitterアカウントを自由に操作できてしまう、セキュリティ上重要な情報です。
このため、プログラムそのものに直に記述(ハードコーディング)してしまうと漏洩時に危険です。
API keyの機能によっては、勝手に開発者アカウントを取得したアカウントで迷惑ツイートを流されたり、不特定多数にDMを送られたり、よく分からない人物をフォローしたりするかもしれません。
(セキュリティは専門ではないので何かツッコミや改善点があればごめんなさい…)
このため、別のjsonファイルにAPI keyを記述し、そちらから読み込むようにします。

今回はAPIkeyが書かれたconfigファイルを変換してjsonファイルを作ってみます。
まずRstudioのConsoleに以下を打ち込みます。

getwd()
Consoleはここ、左下側の窓

getwd()で出てくるファイルパスの中に「config.yml」という名前のテキストファイルを作り、以下の内容を記述します。

default:
  consumer_key: "****"
  consumer_secret: "****"
  access_token: "****"
  access_secret: "****"

****にはTwitter開発者アカウントで取得したconsumer_key、secret、access_token、secretを入れてください。
consumer_key行以下の字下げ(インデント)は半角スペース2個分、最後に改行してください。
sakura editorで作るとこんな感じになります。

作り終えたら保存し、Rstudioのconsoleで以下を実行します。

install.packages("config") # configパッケージのインストール
library(config) # configパッケージの読み込み
config <- config::get() # config.ymlファイルの内容をconfigに格納

こちらでエラーが生じる場合にはconfig.ymlがgetwd()内に作られているか、config.ymlの内容(字下げは半角スペース2個になっているか、最後に改行されているか)が問題ないかをご確認ください。

次に読み込まれたconfigをjsonファイルに変換します。

install.packages("jsonlite") # jsonを扱うjsonliteパッケージのインストール
library(jsonlite) # パッケージの読み込み
write_json(config, ”config.json”) # configの内容をconfig.jsonとしてgetwd()下に書き出し
js <- read_json("config.json", simplifyVector = TRUE) # 書き出したconfig.jsonをjsに格納
js # jsの内容を確認

以下のようにconfig.ymlに入力したAPI keyが出力されれば成功です。

getwd()のファイルパスにAPI keyの入ったconfig.jsonが作成されているはずです。
これでjsonファイルの準備は完了です。

・Rstudioにコードを入れる

いよいよwebアプリを作っていきます。
まずはRstudioに必要なパッケージをインストールします。
以下のコードをRのコンソールに打ち込んでください。

# install packages
install.packages("shiny") # webアプリを作る基本パッケージ
install.packages("shinymanager") # ログイン画面を作る
install.packages("shinythemes") # webアプリの外見テーマを簡単にいじれる用
install.packages("shinybusy") # ツイート取得中のbusyインジケーター表示用
install.packages("rtweet") # ツイート取得用パッケージ
install.packages("tidyverse") # データ整形用
install.packages("DT") # 取得データをインタラクティブな表にして表示する用
install.packages("lubridate") # 時系列データ整形用
install.packages("jsonlite") # jsonファイルの読み込み用

5分程度で必要なパッケージがインストールされます。

次にRstudioの左上メニューのFile→New File→Shiny Web app… を選びます。
アプリ名を適当に英語で入れ、Createを押します。

そうするとgetwd()下にtweet_collectionというフォルダができます。
そのフォルダの中に先ほど作成したconfig.jsonを"コピー"してください。

tweet_collectionの中身はこんな感じ

Rstudioに戻ると、上側のタブにapp.Rが出てきます。
その中身にはshiny WEBアプリのデモが入っているので、全部消します。

左上側の窓にあるコードを選択して…
消す

そして、以下のコードを入れます。

コードを入れるのはココ、左上側の窓


# tweet_collection

# This is a Shiny web application. You can run the application by clicking
# the 'Run App' button above.
#
# Find out more about building applications with Shiny here:
#
#    http://shiny.rstudio.com/
#

# cache clear
rm(list=ls())
gc();  gc();

library("shiny")
library("shinymanager")
library("shinythemes")
library("shinybusy")
library("rtweet")
library("tidyverse")
library("DT")
library("lubridate")
library("jsonlite")


# set credentials
credentials <- data.frame(
  user = c("shiny123", "user1234"), # 
  password = c("azerty123", "pass1234"), # 
  start = c("2019-04-15"), # optinal (all others)
  expire = c(NA, NA),
  admin = c(TRUE, TRUE),
  comment = "",
  stringsAsFactors = FALSE
)

# read API key from json
keys <- read_json("config.json", simplifyVector = TRUE)
twitter_token <- create_token(
  app = "YOUR APP NAME",
  consumer_key = keys$consumer_key,
  consumer_secret = keys$consumer_secret,
  access_token = keys$access_token,
  access_secret = keys$access_secret
)

# Define UI for application that draws a histogram
ui <- fluidPage(
  theme = shinytheme("spacelab"),

  # Application title
  titlePanel("Search tweets"),
  "You can only download a total of ",
  span("18,000 tweets per 15 minutes and tweets within the last seven days.", style = "color:blue"),
  "If it does not work, please try again later.",


  # Sidebar
  sidebarLayout(
    sidebarPanel(
      width = 2,
      numericInput("num_tweets_to_download",
        label = "Number of tweets to download",
        min = 100,
        max = 18000,
        value = 100,
        step = 100
      ),
      textInput("word_to_search",
        label = "word to search",
        value = "#dog"
      ),
      actionButton("get_data", "Get data", class = "btn-primary"),
      br(), br(),
      "Download",
      br(),
      downloadButton("download_data", ".csv")
    ),

    # Show results
    mainPanel(
      width = 10,
      DT::dataTableOutput("tweet_table")
    )
  )
)


# Wrap your UI with secure_app
ui <- secure_app(ui)

# Define server logic
server <- function(input, output, session) {
  # check_credentials returns a function to authenticate users
  res_auth <- secure_server(
    check_credentials = check_credentials(credentials)
  )

  # tweet collection
  tweet_df <- eventReactive(
    input$get_data,
    {
      show_modal_spinner()
      x <- search_tweets(input$word_to_search, n = input$num_tweets_to_download, include_rts = FALSE)
      x
    }
  )

  # tweet_data cleansing
  tweet_table_data <- reactive({
    req(tweet_df())
    x2 <- tweet_df() %>%
      mutate(created_at = ymd_hms(created_at) + 32400) %>% # UST to JST
      select(
        created_at,
        screen_name, text, favorite_count, retweet_count,
        status_url, description, followers_count, friends_count
      )
    x2 <- x2 %>% mutate(url = status_url,
                        status_url = paste0("<a href='", x2$status_url, "'>", x2$status_url, "</a>"))
    remove_modal_spinner()
    x2
  })

  output$tweet_table <- DT::renderDataTable(
    tweet_table_data(),
    escape = FALSE,
    options = list(
      lengthMenu = c(10, 30, 100),
      autoWidth = TRUE,
      pageLength = 30,
      scrollY = "800px",
      scrollX = TRUE,
      scrollCollapse = TRUE
    )
  )

  # download button server logic
  output$download_data <- downloadHandler(
    filename = function() {
      paste(Sys.Date(), input$word_to_search, "_", ".csv", sep = "")
    },
    content = function(file) {
      rtweet::write_as_csv(tweet_table_data() %>% 
                             select(-status_url), 
                           file, fileEncoding = "CP932")
    }
  )
}

# Run the application
shinyApp(ui = ui, server = server)

上記プログラムを記入したら、一か所だけ修正を加えます。

# read API key from json
keys <- read_json("config.json", simplifyVector = TRUE)
twitter_token <- create_token(
  app = "YOUR APP NAME", # ← ココを修正!
  consumer_key = keys$consumer_key,
  consumer_secret = keys$consumer_secret,
  access_token = keys$access_token,
  access_secret = keys$access_secret
)

上から1/3くらいの# read API key from jsonの箇所の
app = "YOUR APP NAME",YOUR APP NAMEをTwitter開発者アカウントで設定したAPI keyのアプリの名前に変更してください。
具体的にはTwitter Developper PortalのProject & Appsにあるやつです。

Project & Appsにあるやつ

ここまで入力すればとりあえずOKです。

ここからは改造したい方など向けに個別のコードについて簡単に解説しますが、興味がない方は「・Rstudio上で動作させる」 まで飛ばしてください。

・コードの内容
コードはwebアプリのユーザーインターフェースを記述するuiと、処理内容を記述するserverに分かれており、Rのshinyパッケージを用いて作成されています。
shinyの詳細は以下のサイトを参照してください。

・ログインページについて

# set credentials
credentials <- data.frame(
  user = c("shiny123", "user1234"), # USER ID
  password = c("azerty123", "pass1234"), # PASSWORD
  start = c("2019-04-15"), # optinal (all others)
  expire = c(NA, NA),
  admin = c(TRUE, TRUE),
  comment = "",
  stringsAsFactors = FALSE
)

こちらとserverのところres_authのところと、
ui <- secure_app(ui) でログインページを設定しています。
API keyには15分間18,000ツイートという制限があります。
WEBアプリを公開して色んな人が使うとすぐに制限にひっかかってしまいます。
このため簡単なログインページを使って決められた人しか使えないようにします。
この例では以下の方のみログイン可能です。
①ユーザー1
ID: shiny123
PASS: azerty123
②ユーザー2
ID: user1234
PASS: pass1234

お好みのログインIDとPASS、人数に編集してご使用ください。
例えば、ここにユーザー3(ID: user3  PASS: pass3)を追加したい場合には以下のようにします。

# set credentials
credentials <- data.frame(
  user = c("shiny123", "user1234", "user3"), # USER ID
  password = c("azerty123", "pass1234", "pass3"), # PASSWORD
  start = c("2019-04-15"), # optinal (all others)
  expire = c(NA, NA, NA),
  admin = c(TRUE, TRUE, TRUE),
  comment = "",
  stringsAsFactors = FALSE
)

セキュリティとか言ってたのにログインIDとパスワードがハードコーディングされてるじゃないか!
というツッコミについては仰る通り!!!!
まぁ…ツイッター見れるだけのアプリですし…
Rに詳しい人はjsonにuserとpasswordの中身を入れるのもアリだと思います。

・サイドバー

  # Sidebar
  sidebarLayout(
    sidebarPanel(
      width = 2,
      numericInput("num_tweets_to_download",
        label = "Number of tweets to download",
        min = 100,
        max = 18000,
        value = 100,
        step = 100
      ),
      textInput("word_to_search",
        label = "word to search",
        value = "#cat"
      ),
      actionButton("get_data", "Get data", class = "btn-primary"),
      br(), br(),
      "Download",
      br(),
      downloadButton("download_data", ".csv")
    ),

ここの部分を作ってるコードです。
numericInputで検索数の設定を、検索制限のため上限を18000までにしてます。
textInputで検索ワード入力欄。
actionButtonで検索開始ボタン。
downloadButtonでダウンロードボタンを作っています。


・メイン表示画面

    # Show results
    mainPanel(
      width = 10,
      DT::dataTableOutput("tweet_table")
    )

検索結果を表示するメイン画面を作成しています。
shiny上で表を良い感じに表示できるDTパッケージを使用していますが、詳細な設定はserver部分でやっています。

こんな感じに表示されます

・ツイートの収集

  # tweet collection
  tweet_df <- eventReactive(
    input$get_data,
    {
      show_modal_spinner()
      x <- search_tweets(input$word_to_search, n = input$num_tweets_to_download, include_rts = FALSE)
      x
    }
  )

eventReactive関数を利用し、ボタンを押した際に動くようになっています。
uiで受け取ったinputを使って、rtweetパッケージのsearch_tweets関数を用いて、収集しています。
ここをrtweetのget_timeline関数にすれば指定した人のツイートを3200まで取得したりもできます。
shinyに詳しい人ならnavbarPageでナビゲーションバーのタブで機能を切り替えられるようにすることもできます。
また、収集には結構時間がかかるため、shinybusyパッケージのshow_modal_apinnerでbusyなぐるぐるマークを出してやります。

・取得ツイートデータの整形・整理

  # tweet_data cleansing
  tweet_table_data <- reactive({
    req(tweet_df())
    x2 <- tweet_df() %>%
      mutate(created_at = ymd_hms(created_at) + 32400) %>% # UST to JST
      select(
        created_at,
        screen_name, text, favorite_count, retweet_count,
        status_url, description, followers_count, friends_count, source
      )
    x2 <- x2 %>% mutate(url = status_url,
                        status_url = paste0("<a href='", x2$status_url, "'>", x2$status_url, "</a>"))
    remove_modal_spinner()
    x2
  })

reactiveとreqを使って、ツイートデータが収集されることでこちらのコードが動くようになっています。
取得されたツイートデータはUTC標準時なので、lubridateパッケージでymd_hms形式にしてから32400秒を足してJST日本時間に変換してやります。
また、収集されるデータは90行あるデータですが、その中で必要なデータだけをselectで抽出してやります。
created_at(ツイート時間)、screen_name(ツイートした人のID)、text(本文)…等々
こちらをいじってやればハッシュタグのデータや画像の有無などを追加したりできます。
また、DTパッケージで表示されるツイートのリンク(status_url)はアクティブでないためクリックしてもそのツイートに飛ぶことができません。
こちらにをhtmlタグ<a href=""></a>をつけて、表上でクリックしたら当該ツイートに飛べるようにしてやります。
ダウンロードした時にhtmlタグがついているとエクセル上で飛べずに面倒なので、そのままのurlの列も追加してやります。
ダウンロード時に戻すの面倒になった…
処理が終わったらremove_modal_spinnerでぐるぐるを消してやります。

・インタラクティブな表の表示

DTパッケージでインタラクティブな表を表示してやります。

  output$tweet_table <- DT::renderDataTable(
    tweet_table_data(),
    escape = FALSE,
    options = list(
      lengthMenu = c(10, 30, 100),
      autoWidth = TRUE,
      pageLength = 30,
      scrollY = "800px",
      scrollX = TRUE,
      scrollCollapse = TRUE
    )
  )

DTパッケージは色んな機能があってスゴイのですが、ここでは一度に表示できる量やスクロールバーを設定しています。
それとリンクをクリックできるようにhtmlタグ<a href=""></a>を有効化するため、escape=FALSEにしてます。
改造したい方は詳しくは下のページへ。

https://rstudio.github.io/DT/shiny.html

・ダウンロード

ダウンロードボタンの動作を作ってやります。

  # download button server logic
  output$download_data <- downloadHandler(
    filename = function() {
      paste(Sys.Date(), input$word_to_search, "_", ".csv", sep = "")
    },
    content = function(file) {
      rtweet::write_as_csv(tweet_table_data() %>% 
                             select(-status_url), 
                           file, fileEncoding = "CP932")
    }
  )

ファイル名のデフォルトを自動で今日の日付+検索ワードにするようにしてあります。
また、ダウンロードするファイルのエンコードをこちらで決めてやります。
rtweetで収集されるデータはデフォルトではUTF-8なのでそのままではwindows上で文字化けします。
CP932は犠牲になったのだ
今回はwindows向けでCP932にしてありますが、macやLinuxでは"UTF-8"にしてやってください。
エクセルで意味のない表示用のhtmlタグ付きのstatus_urlを消し、元々のurlだけ残してやります。
ダウンロード用の関数はwrite.csvだとカンマ区切りで列がおかしなことになりやすい、list形式のデータを保管できないため、rtweetパッケージのwrite_as_csvを使ってみました。

・Rstudio上で動作させる

ここまで来たらRstudioの左上のメニューからFile→ Save with Encoding…→UTF-8を押します。
これで作ったプログラムがUTF-8のエンコーディング形式で保存されます。
UTF-8でないとWEBにアップロードするステップでエラーが発生します。
CP932は犠牲になったのだ…

その後、Run Appを押せば動きます。

おもむろに押す
こんなログイン画面が出ればひとまず動作成功

Usernameに「shiny123」
Passwordに「azerty123」
を入れるとツイート収集ページにログインできます。

Number of tweetsに収集するツイート数を入力(最大18,000)
word of searchに検索ワードを入力
Get dataを押すとデータが収集できます。
取得できない場合はエラーメッセージを参考に、search_tweetやAPI key周りをご確認ください。

こんな風にツイートが表示されれば大成功

収集されたツイートは各列の▼を押すことで降順昇順に並び替えたり、Searchで絞り込むことが可能です。
また左メニューのDownloadでエクセル.csvファイルでダウンロードが可能です。

Good!!!!

個人で使う分にはこのようにRstudio上で動作させても十分です。

・shinyappsにアップロードしweb上で動作させる

作成したアプリはshinyappsというサービスを使うと簡単にwebアプリとして公開することができます。
しかも5アプリ、月25稼働時間までは無料です。
つまりスマホやPCでどこでもツイート収集が出来るようになりますし、仕事で使ったり、誰かに送って使ってもらったりもできます。
WEBアプリお貢ぎができる時代!!!!

上記ページからサインアップし
 ACCOUNT SETUPで公開するURLの名前を適当になんかカッコイイ感じで決めます。

shinyappsの左メニューのApplicationsのGETTING STARTEDページに従ってRstudio上で以下の操作を行います。

・rsconnectパッケージをインストール
shinyappsを公開するためのrsconnectパッケージをインストールします。
以下のコマンドをRstudioのconsoleに打ちます。

install.packages('rsconnect')

次にshinyappsとRstudioをリンクさせます。
****にはshinyappsのGETTING STARTEDページに表示されている情報をRstudioのConsoleに入力してください。

rsconnect::setAccountInfo(name='*****',
			  token='*****',
			  secret='*****')
GETTING STARTEDページのここを押してコピーすると便利

さて、いよいよWEBアプリを公開(Deploy)…と行きたいところですが…
コードや環境が日本語環境でマルチバイトを含む、Windows(CP932)だったりするとうまくいかない場合が多いです。
CP932は犠牲になったのだ…
参考:

そこで以下のように入力し、一旦RstudioのエンコードをUTF-8にしてからRstudioのConsoleからDeployします。

tmp.enc <- options()$encoding # 標準コーディングを記録(native.encであることが多いです)
options(encoding = "UTF-8") # エンコーディングをUTF-8に変更
rsconnect::deployApp('path/to/your/app')
options(encoding = tmp.enc) # エンコーディングをもとに戻す

'path/to/your/app'はconfig.jsonファイルとapp.Rが入っているところです。C:\R\tweet_collectionに入っているなら以下のようにします。

rsconnect::deployApp('C:/R/tweet_collection')

Windowsのエクスプローラーからコピペできる文字列とスラッシュが逆なのでご注意ください。

これを動作させることで、うまく行けば作成したWEBアプリを公開できるはずです。

URLをコピーして動作していることを確かめましょう。

スマホでも動く!

18,000ツイート収集すると動かなくなるので15分待ちましょう。
また、無料API keyの仕様上、過去7日間しかデータを遡れません。
更に、shinnyapps上で動作させてWindowsにデータを保存した際、ツイート文章にコンマがあったりするとエクセルの列がズレることがあります。
これはshinyappsがLINUX文字コードUTF-8で動作しており、CSVファイル保存の際にCP932に保存することが要因です。
これを防ぐにはserverのダウンロード部分を

  # download button server logic
  output$download_data <- downloadHandler(
    filename = function() {
      paste(Sys.Date(), input$word_to_search, "_", ".csv", sep = "")
    },
    content = function(file) {
      rtweet::write_as_csv(tweet_table_data() %>% 
                             select(-status_url), 
                           file, fileEncoding = "UTF-8") # CP932→UTF-8
    }
  )

と書き換えるとダウンロードしたファイルが文字化けしまくりますが…
それをR上でreadr::read_csv→write.csv(…, fileEncoding = "CP932")してUTF-8→CP932をlocal上で変換してやればちゃんと読み込めることがあります。
面倒ですね…。CP932は犠牲になったのだ…
shinyappsではなくLocalで動作させる、MacやLinuxにUTF-8で保存するという方法もあります。

ツイートをもっと遡りたい人はget_timeline関数を使えば特定のアカウントの3200ツイートを収集できますが…その拡張については気が向いたら別途記事を書くかもしれません。

↓書きました


●終わりに

今回はRとshinyでTwitterのwebアプリを作ってみました。
本当は3-legged Oauthでユーザーのアクセスキーを使用する仕様で作りたかったのですが、そこまでは実力が足りなかった…。
見ていただいた方、作っていただいた方がいましたらありがとうございます。
このwebアプリがあれば、ツイートや人の検索ができてTwitterライフが捗り、やろうと思えば過去に書いたnoteのような本格的なTwitterの分析もできます。
無料でこんなことができてしまうという、作れてしまうということは素敵なことではないでしょうか。
もしエラーがあったり分からない点、疑問点や改善点があればTwitterにDMをお願いいたします。
できる範囲で対応させていただきます。
プログラミングは素人なので対応できないかもですが…。

物を作ることは楽しく、辛く、苦しく、それが動いた時の喜びは例えようのないものです。
作ることを通じて充実した時間を過ごせましたら幸いです。

●参考

・Shiny Tutorial

・Shinyapps.io にUTF8の文字列(日本語)を利用したアプリをデプロイする

・rtweet

・Using DT in Shiny

・shiny manager


万が一サポート、感想、コメント、分析等のご相談などございましたらお気軽に。