前回までのrPubsページ
- 第1章:準備運動
前回引き続き、言語処理100本ノック(2015年版)を解きます。
(下記の『前書き(言語処理100本ノックについて)』は前回と同じです)
前書き(言語処理100本ノックについて)
- 本稿では、東北大学の乾・岡崎研究室で公開されている言語処理100本ノック(2015年版)を、R言語で解いていきます。
- 改訂前の言語処理100本ノックも同様に上記研究室のサイトにあります。
前書き(Rに関して)
- Rの構文や関数についての説明は一切ありませんので、あらかじめご了承ください。
- 本稿では、{base}にある文字列処理ではなく、{stringr}(1.0.0以上)とパイプ処理を極力用いております({stringi}も処理に応じて活用していきます)。課題によってはパイプ処理でこなすのに向かない状況もありますので、あらかじめご了承ください。
- 今回は上記に加え、{readr}を用いてファイル読み込みをしていきます。
参考ページ
{stringr}と{stringi}
hadley/stringr
RPubs - このパッケージがすごい2014: stringr
stringiで輝く☆テキストショリスト
stringr 1.0.0を使ってみる
ご意見やご指摘など
- こうした方が良いやこういう便利な関数がある、間違いがあるなど、ご指摘をお待ちしております。
- 下記のいずれかでご連絡・ご報告いただけますと励みになります(なお、Gitに慣れていない人です)。
Twitter, GitHub
以下、ひたすら解いていきます。
各チャンク内の「TASK_UNIX_XXX_COMMAND_XXX」という定数は、確認用UNIXコマンドの文字列です。
library(knitr)
library(readr)
library(dplyr)
library(stringr)
library(stringi)
knitr::opts_chunk$set(comment = NA)
# 第1章の入力データURL(固定)
TASK_INPUT_URL <- "http://www.cl.ecei.tohoku.ac.jp/nlp100/data/hightemp.txt"
# 入力データのカラム名(指定)
TASK_INPUT_COL_NAME <- c("prefecture", "observation", "temperature", "date")
# 問題中で指定する読み込み列数(指定)
TASK_SELECT_N <- 10
# 複数の課題で必要とされる加工を加えず入力データを読み込んでおく
TASK_INPUT_DATA <- readr::read_lines(file = TASK_INPUT_URL, n_max = -1)
# 複数の課題で必要とされるファイル名を、UNIXコマンド用に取得しておく
TASK_FILE_NAME <- basename(TASK_INPUT_URL)
# ファイル取得
download.file(
url = TASK_INPUT_URL, destfile = TASK_FILE_NAME,
method = "wget", quiet = FALSE
)
file.exists(file1 = TASK_FILE_NAME)
[1] TRUE
行数をカウントせよ.確認にはwcコマンドを用いよ.
TASK_UNIX_COMMAND_10 <- c("wc -l")
length(x = TASK_INPUT_DATA)
[1] 24
# wc -l hightemp.txt
system(
command = stringr::str_c(TASK_UNIX_COMMAND_10, TASK_FILE_NAME, sep = " "),
intern = TRUE
) %>%
stringr::str_trim(side = "left")
[1] "24 hightemp.txt"
タブ1文字につきスペース1文字に置換せよ.確認にはsedコマンド,trコマンド,もしくはexpandコマンドを用いよ.
# タブとスペースをエスケープしておく
TASK_UNIX_COMMAND_11 <- list(
TR = c(
"tr",
shQuote(string = "\t", type = "sh"), shQuote(string = " ", type = "sh"),
"<"
),
EX = c("expand", "-t", "1")
)
stringr::str_replace_all(
string = TASK_INPUT_DATA,
pattern = "\t", replacement = " "
)
[1] "高知県 江川崎 41 2013-08-12"
[2] "埼玉県 熊谷 40.9 2007-08-16"
[3] "岐阜県 多治見 40.9 2007-08-16"
[4] "山形県 山形 40.8 1933-07-25"
[5] "山梨県 甲府 40.7 2013-08-10"
[6] "和歌山県 かつらぎ 40.6 1994-08-08"
[7] "静岡県 天竜 40.6 1994-08-04"
[8] "山梨県 勝沼 40.5 2013-08-10"
[9] "埼玉県 越谷 40.4 2007-08-16"
[10] "群馬県 館林 40.3 2007-08-16"
[11] "群馬県 上里見 40.3 1998-07-04"
[12] "愛知県 愛西 40.3 1994-08-05"
[13] "千葉県 牛久 40.2 2004-07-20"
[14] "静岡県 佐久間 40.2 2001-07-24"
[15] "愛媛県 宇和島 40.2 1927-07-22"
[16] "山形県 酒田 40.1 1978-08-03"
[17] "岐阜県 美濃 40 2007-08-16"
[18] "群馬県 前橋 40 2001-07-24"
[19] "千葉県 茂原 39.9 2013-08-11"
[20] "埼玉県 鳩山 39.9 1997-07-05"
[21] "大阪府 豊中 39.9 1994-08-08"
[22] "山梨県 大月 39.9 1990-07-19"
[23] "山形県 鶴岡 39.9 1978-08-03"
[24] "愛知県 名古屋 39.9 1942-08-02"
# tr "\t" " " < hightemp.txt
system(
command = stringr::str_c(c(TASK_UNIX_COMMAND_11$TR, TASK_FILE_NAME), collapse = " "),
intern = TRUE
)
[1] "高知県 江川崎 41 2013-08-12"
[2] "埼玉県 熊谷 40.9 2007-08-16"
[3] "岐阜県 多治見 40.9 2007-08-16"
[4] "山形県 山形 40.8 1933-07-25"
[5] "山梨県 甲府 40.7 2013-08-10"
[6] "和歌山県 かつらぎ 40.6 1994-08-08"
[7] "静岡県 天竜 40.6 1994-08-04"
[8] "山梨県 勝沼 40.5 2013-08-10"
[9] "埼玉県 越谷 40.4 2007-08-16"
[10] "群馬県 館林 40.3 2007-08-16"
[11] "群馬県 上里見 40.3 1998-07-04"
[12] "愛知県 愛西 40.3 1994-08-05"
[13] "千葉県 牛久 40.2 2004-07-20"
[14] "静岡県 佐久間 40.2 2001-07-24"
[15] "愛媛県 宇和島 40.2 1927-07-22"
[16] "山形県 酒田 40.1 1978-08-03"
[17] "岐阜県 美濃 40 2007-08-16"
[18] "群馬県 前橋 40 2001-07-24"
[19] "千葉県 茂原 39.9 2013-08-11"
[20] "埼玉県 鳩山 39.9 1997-07-05"
[21] "大阪府 豊中 39.9 1994-08-08"
[22] "山梨県 大月 39.9 1990-07-19"
[23] "山形県 鶴岡 39.9 1978-08-03"
[24] "愛知県 名古屋 39.9 1942-08-02"
# expand -t 1 hightemp.txt
system(
command = stringr::str_c(c(TASK_UNIX_COMMAND_11$EX, TASK_FILE_NAME), collapse = " "),
intern = TRUE
)
[1] "高知県 江川崎 41 2013-08-12"
[2] "埼玉県 熊谷 40.9 2007-08-16"
[3] "岐阜県 多治見 40.9 2007-08-16"
[4] "山形県 山形 40.8 1933-07-25"
[5] "山梨県 甲府 40.7 2013-08-10"
[6] "和歌山県 かつらぎ 40.6 1994-08-08"
[7] "静岡県 天竜 40.6 1994-08-04"
[8] "山梨県 勝沼 40.5 2013-08-10"
[9] "埼玉県 越谷 40.4 2007-08-16"
[10] "群馬県 館林 40.3 2007-08-16"
[11] "群馬県 上里見 40.3 1998-07-04"
[12] "愛知県 愛西 40.3 1994-08-05"
[13] "千葉県 牛久 40.2 2004-07-20"
[14] "静岡県 佐久間 40.2 2001-07-24"
[15] "愛媛県 宇和島 40.2 1927-07-22"
[16] "山形県 酒田 40.1 1978-08-03"
[17] "岐阜県 美濃 40 2007-08-16"
[18] "群馬県 前橋 40 2001-07-24"
[19] "千葉県 茂原 39.9 2013-08-11"
[20] "埼玉県 鳩山 39.9 1997-07-05"
[21] "大阪府 豊中 39.9 1994-08-08"
[22] "山梨県 大月 39.9 1990-07-19"
[23] "山形県 鶴岡 39.9 1978-08-03"
[24] "愛知県 名古屋 39.9 1942-08-02"
# Mac環境だとsedで"\t"が認識されないという症状があるそうで、確認できず
各行の1列目だけを抜き出したものをcol1.txtに,2列目だけを抜き出したものをcol2.txtとしてファイルに保存せよ.確認にはcutコマンドを用いよ.
TASK_UNIX_COMMAND_12 <- c("cut -f")
# 出力ファイル名と抜き出す列番号を対応させたベクトル
TASK_SELECT_COL_NUM <- c("col1.txt" = 1, "col2.txt" = 2)
# col_types引数でカラム指定したreadr::read_tsv()でも可能(17.の問題にて)
do.call(
what = "cbind",
args = lapply(
X = TASK_SELECT_COL_NUM,
FUN = function (i) {
select_res <- stringr::str_split_fixed(
string = TASK_INPUT_DATA,
pattern = "\t",
n = i + 1
)[, i] %>%
data.frame %>%
dplyr::rename_(.dots = setNames(".", TASK_INPUT_COL_NAME[i]))
readr::write_delim(
x = select_res,
path = names(TASK_SELECT_COL_NUM)[i],
delim = "\n",
append = FALSE, col_names = FALSE
)
return(select_res)
}
)
)
prefecture observation
1 高知県 江川崎
2 埼玉県 熊谷
3 岐阜県 多治見
4 山形県 山形
5 山梨県 甲府
6 和歌山県 かつらぎ
7 静岡県 天竜
8 山梨県 勝沼
9 埼玉県 越谷
10 群馬県 館林
11 群馬県 上里見
12 愛知県 愛西
13 千葉県 牛久
14 静岡県 佐久間
15 愛媛県 宇和島
16 山形県 酒田
17 岐阜県 美濃
18 群馬県 前橋
19 千葉県 茂原
20 埼玉県 鳩山
21 大阪府 豊中
22 山梨県 大月
23 山形県 鶴岡
24 愛知県 名古屋
# cut -f 1 hightemp.txt
# cut -f 2 hightemp.txt
sapply(TASK_SELECT_COL_NUM, function (i) {
system(
command = stringr::str_c(c(TASK_UNIX_COMMAND_12, TASK_SELECT_COL_NUM[i], TASK_FILE_NAME), collapse = " "),
intern = TRUE
)
})
col1.txt col2.txt
[1,] "高知県" "江川崎"
[2,] "埼玉県" "熊谷"
[3,] "岐阜県" "多治見"
[4,] "山形県" "山形"
[5,] "山梨県" "甲府"
[6,] "和歌山県" "かつらぎ"
[7,] "静岡県" "天竜"
[8,] "山梨県" "勝沼"
[9,] "埼玉県" "越谷"
[10,] "群馬県" "館林"
[11,] "群馬県" "上里見"
[12,] "愛知県" "愛西"
[13,] "千葉県" "牛久"
[14,] "静岡県" "佐久間"
[15,] "愛媛県" "宇和島"
[16,] "山形県" "酒田"
[17,] "岐阜県" "美濃"
[18,] "群馬県" "前橋"
[19,] "千葉県" "茂原"
[20,] "埼玉県" "鳩山"
[21,] "大阪府" "豊中"
[22,] "山梨県" "大月"
[23,] "山形県" "鶴岡"
[24,] "愛知県" "名古屋"
12で作ったcol1.txtとcol2.txtを結合し,元のファイルの1列目と2列目をタブ区切りで並べたテキストファイルを作成せよ.確認にはpasteコマンドを用いよ.
TASK_UNIX_COMMAND_13 <- c("paste", "-d", shQuote(string = "\t", type = "sh"))
TASK_FILE_NAME_13 <- c("col1.txt", "col2.txt")
TASK_SEP_13 <- c("\t")
TASK_OUTPUT_FILE_NAME_13 <- "col1col2.txt"
sapply(TASK_FILE_NAME_13, read_lines) %>%
apply(MARGIN = 1, FUN = stringr::str_c, collapse = TASK_SEP_13) %>%
as.data.frame %>%
write_delim(
path = TASK_OUTPUT_FILE_NAME_13, delim = "",
append = FALSE, col_names = FALSE
)
readr::read_lines(file = TASK_OUTPUT_FILE_NAME_13, n_max = -1)
[1] "高知県\t江川崎" "埼玉県\t熊谷" "岐阜県\t多治見"
[4] "山形県\t山形" "山梨県\t甲府" "和歌山県\tかつらぎ"
[7] "静岡県\t天竜" "山梨県\t勝沼" "埼玉県\t越谷"
[10] "群馬県\t館林" "群馬県\t上里見" "愛知県\t愛西"
[13] "千葉県\t牛久" "静岡県\t佐久間" "愛媛県\t宇和島"
[16] "山形県\t酒田" "岐阜県\t美濃" "群馬県\t前橋"
[19] "千葉県\t茂原" "埼玉県\t鳩山" "大阪府\t豊中"
[22] "山梨県\t大月" "山形県\t鶴岡" "愛知県\t名古屋"
# paste -d "\t" col1.txt col2.txt
system(
command = stringr::str_c(c(TASK_UNIX_COMMAND_13, TASK_FILE_NAME_13), collapse = " "),
intern = TRUE
)
[1] "高知県\t江川崎" "埼玉県\t熊谷" "岐阜県\t多治見"
[4] "山形県\t山形" "山梨県\t甲府" "和歌山県\tかつらぎ"
[7] "静岡県\t天竜" "山梨県\t勝沼" "埼玉県\t越谷"
[10] "群馬県\t館林" "群馬県\t上里見" "愛知県\t愛西"
[13] "千葉県\t牛久" "静岡県\t佐久間" "愛媛県\t宇和島"
[16] "山形県\t酒田" "岐阜県\t美濃" "群馬県\t前橋"
[19] "千葉県\t茂原" "埼玉県\t鳩山" "大阪府\t豊中"
[22] "山梨県\t大月" "山形県\t鶴岡" "愛知県\t名古屋"
自然数Nをコマンドライン引数などの手段で受け取り,入力のうち先頭のN行だけを表示せよ.確認にはheadコマンドを用いよ.
TASK_UNIX_COMMAND_14 <- c("head", "-n")
# 下記で「10」を手入力するが{knitr}でHTML生成する際にエラーになるので、あらかじめ入力しておいた数値を使用
# TASK_SELECT_N <- readline(prompt = "INPUT N: ") %>%
# as.integer
readr::read_lines(file = TASK_INPUT_URL, n_max = TASK_SELECT_N)
[1] "高知県\t江川崎\t41\t2013-08-12"
[2] "埼玉県\t熊谷\t40.9\t2007-08-16"
[3] "岐阜県\t多治見\t40.9\t2007-08-16"
[4] "山形県\t山形\t40.8\t1933-07-25"
[5] "山梨県\t甲府\t40.7\t2013-08-10"
[6] "和歌山県\tかつらぎ\t40.6\t1994-08-08"
[7] "静岡県\t天竜\t40.6\t1994-08-04"
[8] "山梨県\t勝沼\t40.5\t2013-08-10"
[9] "埼玉県\t越谷\t40.4\t2007-08-16"
[10] "群馬県\t館林\t40.3\t2007-08-16"
# head -n 10 hightemp.txt
system(
command = stringr::str_c(c(TASK_UNIX_COMMAND_14, TASK_SELECT_N, TASK_FILE_NAME), collapse = " "),
intern = TRUE
)
[1] "高知県\t江川崎\t41\t2013-08-12"
[2] "埼玉県\t熊谷\t40.9\t2007-08-16"
[3] "岐阜県\t多治見\t40.9\t2007-08-16"
[4] "山形県\t山形\t40.8\t1933-07-25"
[5] "山梨県\t甲府\t40.7\t2013-08-10"
[6] "和歌山県\tかつらぎ\t40.6\t1994-08-08"
[7] "静岡県\t天竜\t40.6\t1994-08-04"
[8] "山梨県\t勝沼\t40.5\t2013-08-10"
[9] "埼玉県\t越谷\t40.4\t2007-08-16"
[10] "群馬県\t館林\t40.3\t2007-08-16"
自然数Nをコマンドライン引数などの手段で受け取り,入力のうち末尾のN行だけを表示せよ.確認にはtailコマンドを用いよ.
TASK_UNIX_COMMAND_15 <- c("tail", "-n")
# 下記で「10」を手入力するが{knitr}でHTML生成する際にエラーになるので、あらかじめ入力しておいた数値を使用
# TASK_SELECT_N <- readline(prompt = "INPUT N: ") %>%
# as.integer
# ファイルを全て読み込んでから、末尾のN行を表示
readr::read_lines(file = TASK_INPUT_URL, n_max = -1) %>%
tail(n = TASK_SELECT_N)
[1] "愛媛県\t宇和島\t40.2\t1927-07-22" "山形県\t酒田\t40.1\t1978-08-03"
[3] "岐阜県\t美濃\t40\t2007-08-16" "群馬県\t前橋\t40\t2001-07-24"
[5] "千葉県\t茂原\t39.9\t2013-08-11" "埼玉県\t鳩山\t39.9\t1997-07-05"
[7] "大阪府\t豊中\t39.9\t1994-08-08" "山梨県\t大月\t39.9\t1990-07-19"
[9] "山形県\t鶴岡\t39.9\t1978-08-03" "愛知県\t名古屋\t39.9\t1942-08-02"
# tail -n 10 hightemp.txt
system(
command = stringr::str_c(c(TASK_UNIX_COMMAND_15, TASK_SELECT_N, TASK_FILE_NAME), collapse = " "),
intern = TRUE
)
[1] "愛媛県\t宇和島\t40.2\t1927-07-22" "山形県\t酒田\t40.1\t1978-08-03"
[3] "岐阜県\t美濃\t40\t2007-08-16" "群馬県\t前橋\t40\t2001-07-24"
[5] "千葉県\t茂原\t39.9\t2013-08-11" "埼玉県\t鳩山\t39.9\t1997-07-05"
[7] "大阪府\t豊中\t39.9\t1994-08-08" "山梨県\t大月\t39.9\t1990-07-19"
[9] "山形県\t鶴岡\t39.9\t1978-08-03" "愛知県\t名古屋\t39.9\t1942-08-02"
自然数Nをコマンドライン引数などの手段で受け取り,入力のファイルを行単位でN分割せよ.同様の処理をsplitコマンドで実現せよ.
TASK_UNIX_COMMAND_16 <- c("split", "-a", "3", "-l")
# 下記で「10」を手入力するが{knitr}でHTML生成する際にエラーになるので、あらかじめ入力しておいた数値を使用
# TASK_SELECT_N <- readline(prompt = "INPUT N: ") %>%
# as.integer
div_num <- as.integer(length(TASK_INPUT_DATA) / TASK_SELECT_N) + 1
group_id <- as.integer(seq(from = 0, to = length(TASK_INPUT_DATA) - 1) / TASK_SELECT_N) + 1
# group_id <- rep(
# x = seq(from = 1, to = div_num),
# each = TASK_SELECT_N
# )[seq(from = 1, to = length(TASK_INPUT_DATA))]
readr::read_lines(file = TASK_INPUT_URL, n_max = -1) %>%
data.frame(x = .) %>%
dplyr::mutate(
group_id = group_id
) %>%
split(x = ., f = .["group_id"]) %>%
lapply(
function(y) {
return(
y %>%
dplyr::select(-group_id) %>%
unlist %>%
as.character
)
}
)
$`1`
[1] "高知県\t江川崎\t41\t2013-08-12"
[2] "埼玉県\t熊谷\t40.9\t2007-08-16"
[3] "岐阜県\t多治見\t40.9\t2007-08-16"
[4] "山形県\t山形\t40.8\t1933-07-25"
[5] "山梨県\t甲府\t40.7\t2013-08-10"
[6] "和歌山県\tかつらぎ\t40.6\t1994-08-08"
[7] "静岡県\t天竜\t40.6\t1994-08-04"
[8] "山梨県\t勝沼\t40.5\t2013-08-10"
[9] "埼玉県\t越谷\t40.4\t2007-08-16"
[10] "群馬県\t館林\t40.3\t2007-08-16"
$`2`
[1] "群馬県\t上里見\t40.3\t1998-07-04" "愛知県\t愛西\t40.3\t1994-08-05"
[3] "千葉県\t牛久\t40.2\t2004-07-20" "静岡県\t佐久間\t40.2\t2001-07-24"
[5] "愛媛県\t宇和島\t40.2\t1927-07-22" "山形県\t酒田\t40.1\t1978-08-03"
[7] "岐阜県\t美濃\t40\t2007-08-16" "群馬県\t前橋\t40\t2001-07-24"
[9] "千葉県\t茂原\t39.9\t2013-08-11" "埼玉県\t鳩山\t39.9\t1997-07-05"
$`3`
[1] "大阪府\t豊中\t39.9\t1994-08-08" "山梨県\t大月\t39.9\t1990-07-19"
[3] "山形県\t鶴岡\t39.9\t1978-08-03" "愛知県\t名古屋\t39.9\t1942-08-02"
# split -a 3 -l 10 hightemp.txt
# xaaa, xaab, xaacの3ファイルが作成される
# 上から順に、それぞれ10行、10行、4行のデータが書き込まれる
system(
command = stringr::str_c(c(TASK_UNIX_COMMAND_16, TASK_SELECT_N, TASK_FILE_NAME), collapse = " "),
intern = TRUE
)
character(0)
1列目の文字列の種類(異なる文字列の集合)を求めよ.確認にはsort, uniqコマンドを用いよ.
TASK_UNIX_COMMAND_17 <- list(
SORT = c("sort"),
UNIQ = c("uniq")
)
COUNT_COL_17 <- list(
COL_NUM = 4,
SELECT_COL_NUM = 1
)
if (length(COUNT_COL_17$SELECT_COL_NUM) > 1) {
COUNT_COL_17$SELECT_COL_NUM <- COUNT_COL_17$SELECT_COL_NUM[1]
}
# readr::read_tsvのcol_types引数で、COUNT_COL_17$SELECT_COL_NUMで選択したカラムだけを読み込む
col_types_17 <- rep("_", length = COUNT_COL_17$COL_NUM)
col_types_17[COUNT_COL_17$SELECT_COL_NUM] <- "c"
readr::read_tsv(
file = TASK_FILE_NAME,
col_types = stringr::str_c(string = col_types_17, collapse = ""), col_name = FALSE
) %>%
unlist %>%
unique %>%
stringr::str_sort(.)
[1] "愛知県" "愛媛県" "岐阜県" "群馬県" "高知県" "埼玉県"
[7] "山形県" "山梨県" "静岡県" "千葉県" "大阪府" "和歌山県"
# sort col1.txt | uniq
system(
command = stringr::str_c(
stringr::str_c(
c(
TASK_UNIX_COMMAND_17$SORT,
names(which(TASK_SELECT_COL_NUM == COUNT_COL_17$SELECT_COL_NUM))
),
collapse = " "
),
TASK_UNIX_COMMAND_17$UNIQ,
sep = "|"
),
intern = TRUE
)
[1] "千葉県" "埼玉県" "大阪府" "山形県" "山梨県" "岐阜県"
[7] "愛媛県" "愛知県" "群馬県" "静岡県" "高知県" "和歌山県"
各行を3コラム目の数値の逆順で整列せよ(注意: 各行の内容は変更せずに並び替えよ).確認にはsortコマンドを用いよ(この問題はコマンドで実行した時の結果と合わなくてもよい).
TASK_UNIX_COMMAND_18 <- c("sort", "-n", "-t", shQuote(string = "\t", type = "sh"), "-k")
# 17. 同様に選択したカラムだけを読み込む
SORT_COL_18 <- list(
COL_NUM = 4,
SELECT_COL_NUM = 3
)
if (length(SORT_COL_18$SELECT_COL_NUM) > 1) {
SORT_COL_18$SELECT_COL_NUM <- SORT_COL_18$SELECT_COL_NUM[1]
}
col_types_18 <- rep("_", length = SORT_COL_18$COL_NUM)
col_types_18[SORT_COL_18$SELECT_COL_NUM] <- "c"
TASK_INPUT_DATA[
(readr::read_tsv(
file = TASK_FILE_NAME,
col_types = stringr::str_c(string = col_types_18, collapse = ""), col_names = FALSE
) %>% unlist %>%
as.character %>%
stringr::str_order()
)
]
[1] "千葉県\t茂原\t39.9\t2013-08-11"
[2] "埼玉県\t鳩山\t39.9\t1997-07-05"
[3] "大阪府\t豊中\t39.9\t1994-08-08"
[4] "山梨県\t大月\t39.9\t1990-07-19"
[5] "山形県\t鶴岡\t39.9\t1978-08-03"
[6] "愛知県\t名古屋\t39.9\t1942-08-02"
[7] "岐阜県\t美濃\t40\t2007-08-16"
[8] "群馬県\t前橋\t40\t2001-07-24"
[9] "山形県\t酒田\t40.1\t1978-08-03"
[10] "千葉県\t牛久\t40.2\t2004-07-20"
[11] "静岡県\t佐久間\t40.2\t2001-07-24"
[12] "愛媛県\t宇和島\t40.2\t1927-07-22"
[13] "群馬県\t館林\t40.3\t2007-08-16"
[14] "群馬県\t上里見\t40.3\t1998-07-04"
[15] "愛知県\t愛西\t40.3\t1994-08-05"
[16] "埼玉県\t越谷\t40.4\t2007-08-16"
[17] "山梨県\t勝沼\t40.5\t2013-08-10"
[18] "和歌山県\tかつらぎ\t40.6\t1994-08-08"
[19] "静岡県\t天竜\t40.6\t1994-08-04"
[20] "山梨県\t甲府\t40.7\t2013-08-10"
[21] "山形県\t山形\t40.8\t1933-07-25"
[22] "埼玉県\t熊谷\t40.9\t2007-08-16"
[23] "岐阜県\t多治見\t40.9\t2007-08-16"
[24] "高知県\t江川崎\t41\t2013-08-12"
# sort -n -t " " -k 3 hightemp.txt
system(
command = stringr::str_c(c(TASK_UNIX_COMMAND_18, SORT_COL_18$SELECT_COL_NUM, TASK_FILE_NAME), collapse = " "),
intern = TRUE
)
[1] "山形県\t鶴岡\t39.9\t1978-08-03"
[2] "山梨県\t大月\t39.9\t1990-07-19"
[3] "大阪府\t豊中\t39.9\t1994-08-08"
[4] "埼玉県\t鳩山\t39.9\t1997-07-05"
[5] "千葉県\t茂原\t39.9\t2013-08-11"
[6] "愛知県\t名古屋\t39.9\t1942-08-02"
[7] "群馬県\t前橋\t40\t2001-07-24"
[8] "岐阜県\t美濃\t40\t2007-08-16"
[9] "山形県\t酒田\t40.1\t1978-08-03"
[10] "千葉県\t牛久\t40.2\t2004-07-20"
[11] "愛媛県\t宇和島\t40.2\t1927-07-22"
[12] "静岡県\t佐久間\t40.2\t2001-07-24"
[13] "愛知県\t愛西\t40.3\t1994-08-05"
[14] "群馬県\t館林\t40.3\t2007-08-16"
[15] "群馬県\t上里見\t40.3\t1998-07-04"
[16] "埼玉県\t越谷\t40.4\t2007-08-16"
[17] "山梨県\t勝沼\t40.5\t2013-08-10"
[18] "静岡県\t天竜\t40.6\t1994-08-04"
[19] "和歌山県\tかつらぎ\t40.6\t1994-08-08"
[20] "山梨県\t甲府\t40.7\t2013-08-10"
[21] "山形県\t山形\t40.8\t1933-07-25"
[22] "埼玉県\t熊谷\t40.9\t2007-08-16"
[23] "岐阜県\t多治見\t40.9\t2007-08-16"
[24] "高知県\t江川崎\t41\t2013-08-12"
各行の1列目の文字列の出現頻度を求め,その高い順に並べて表示せよ.確認にはcut, uniq, sortコマンドを用いよ.
TASK_UNIX_COMMAND_19 <- list(
CUT = c("cut", "-f", "1"),
UNIQ = c("sort | uniq", "-c"),
SORT = c("sort", "-r")
)
GROUP_BY_KEY_COL_NUM_KEY <- c(1)
if (length(TASK_INPUT_COL_NAME) <= length(GROUP_BY_KEY_COL_NUM_KEY)) {
GROUP_BY_KEY_COL_NUM_KEY <- GROUP_BY_KEY_COL_NUM_KEY[seq(from = 1, to = length(TASK_INPUT_COL_NAME))]
}
# 指定したカラムをキーにグルーピング(設定変更に柔軟に対応できるように、non-standard evaluationの方を使う)して頻度を数え、頻度に応じで並び替え
readr::read_tsv(
file = TASK_FILE_NAME,
col_types = NULL, col_name = TASK_INPUT_COL_NAME
) %>%
dplyr::group_by_(.dots = TASK_INPUT_COL_NAME[GROUP_BY_KEY_COL_NUM_KEY]) %>%
dplyr::summarize(freq = n()) %>%
dplyr::arrange(desc(freq))
Source: local data frame [12 x 2]
prefecture freq
1 埼玉県 3
2 山形県 3
3 山梨県 3
4 群馬県 3
5 千葉県 2
6 岐阜県 2
7 愛知県 2
8 静岡県 2
9 和歌山県 1
10 大阪府 1
11 愛媛県 1
12 高知県 1
# cut -f 1 hightemp.txt | sort | uniq -c | sort -r
system(
command = stringr::str_c(
stringr::str_c(c(TASK_UNIX_COMMAND_19$CUT, TASK_FILE_NAME), collapse = " "),
stringr::str_c(TASK_UNIX_COMMAND_19$UNIQ, collapse = " "),
stringr::str_c(TASK_UNIX_COMMAND_19$SORT, collapse = " "),
sep = " | "
),
intern = TRUE
)
[1] " 3 群馬県" " 3 山梨県" " 3 山形県" " 3 埼玉県"
[5] " 2 静岡県" " 2 愛知県" " 2 岐阜県" " 2 千葉県"
[9] " 1 和歌山県" " 1 高知県" " 1 愛媛県" " 1 大阪府"
言語処理100本ノック(2015年版)のUNIXコマンドの基礎の章をやってみました。
(16.のファイルをN分割する課題、本稿ではN行ずつ書き込んでいますが、「N個のファイルに書き込む」という課題な気がしないでもないです)
今回の方法はファイルサイズが大きくなると難しいと思われます。その場合は、おとなしく{foreach}({pforeach})と{iterators}を組み合わせましょう。
Rでファイルを逆から読み込む良い方法は、ちょっとわからなかったです(一度全部を読み込んでから逆順にするのはスマートではない気がしますが、どうでしょう)。何か案があればアドバイスをいただけると幸いです。
{readr}によるファイルの読み込みはオススメ(詳しくは「参考ページ」を)。今後積極的に使っていきたいです。
# {base}のread.delim()
# 一度ファイルを少し読み込んで、データフレームの各カラムに対してclass()を適用して型を推定
# Dateが文字列扱いされ、stringsAsFactors引数をFALSEで指定しないと因子として扱われる
# colClasses引数をせっせと指定するのはちょっと面倒
read.delim(
file = TASK_INPUT_URL, sep = "\t", header = FALSE,
nrow = 10, stringsAsFactors = FALSE
) %>%
summarise_each(funs(class)) %>%
as.character
[1] "character" "character" "numeric" "character"
# readr::read_delim()だとcol_types引数をNULLにすると型を(いい感じに)推定(楽)
readr::read_delim(
file = TASK_INPUT_URL, delim = "\t",
col_types = NULL, col_names = TASK_INPUT_COL_NAME
) %>%
summarise_each(funs(class)) %>%
as.character
[1] "character" "character" "numeric" "Date"
library(devtools)
devtools::session_info()
Session info --------------------------------------------------------------
setting value
version R version 3.2.0 (2015-04-16)
system x86_64, darwin13.4.0
ui X11
language (EN)
collate ja_JP.UTF-8
tz Asia/Tokyo
Packages ------------------------------------------------------------------
package * version date source
assertthat * 0.1 2013-12-06 CRAN (R 3.2.0)
curl * 0.5 2015-02-01 CRAN (R 3.2.0)
DBI * 0.3.1 2014-09-24 CRAN (R 3.2.0)
devtools 1.7.0 2015-01-17 CRAN (R 3.2.0)
digest * 0.6.8 2014-12-31 CRAN (R 3.2.0)
dplyr 0.4.2 2015-06-07 Github (hadley/dplyr@eed9394)
evaluate * 0.7 2015-04-21 CRAN (R 3.2.0)
formatR * 1.2 2015-04-21 CRAN (R 3.2.0)
htmltools * 0.2.6 2014-09-08 CRAN (R 3.2.0)
knitr 1.10 2015-04-23 CRAN (R 3.2.0)
lazyeval * 0.1.10.9000 2015-06-07 Github (hadley/lazyeval@ecb8dc0)
magrittr * 1.5 2014-11-22 CRAN (R 3.2.0)
R6 * 2.0.1 2014-10-29 CRAN (R 3.2.0)
Rcpp * 0.11.6 2015-05-01 CRAN (R 3.2.0)
readr 0.1.0.9000 2015-06-08 Github (hadley/readr@9006822)
rmarkdown * 0.6.2.4 2015-06-07 Github (rstudio/rmarkdown@8c9e25b)
rstudioapi * 0.3.1 2015-04-07 CRAN (R 3.2.0)
stringi 0.4-1 2014-12-14 CRAN (R 3.2.0)
stringr 1.0.0 2015-04-30 CRAN (R 3.2.0)
yaml * 2.1.13 2014-06-12 CRAN (R 3.2.0)