請寫一個函數 insert_spaces()
,用來將傳入的字串的各個字元之間插入空白。此函數會在後面的題目用到。
要求:
stringr
以及 base R 的 grep
系列函數 (見 ?grep
內出現的函數)strsplit()
, sapply()
與 paste()
<- function(x) {
insert_spaces # Write your code here
return(sapply(x, function(s) paste(unlist(strsplit(s, "")), collapse = " "), USE.NAMES = FALSE))
}
#### Do not modify the code below ####
insert_spaces("abc")
insert_spaces(c("abc", "defg", "12345"))
# Should print out
#> [1] "a b c"
#> [1] "a b c" "d e f g" "1 2 3 4 5"
#> [1] "a b c"
#> [1] "a b c" "d e f g" "1 2 3 4 5"
作業的 repo 中有一份純文字檔 idioms.txt
。idioms.txt
是一個成語字典,裡面的每一行是一筆成語的資料,請先觀察這份純文字檔案的規律:
【澡身浴德】 《禮記·儒行》:“儒有澡身而浴德。”孔穎達疏:“澡身,謂能澡潔其身不染濁也;浴德,謂沐浴於德以德自清也。”謂修養身心,使之高潔。
【枕麹藉糟】 枕著酒,墊著酒糟。謂嗜酒,醉酒。
【正本清源】 從根源上進行整頓清理。
【認雞作鳳】 佛教語。謂認凡庸為珍貴。
【擊轂摩肩】 形容車馬眾多。語出《戰國策·齊策一》:“臨淄之涂,車轂擊,人肩摩。”
【鳥覆危巢】 鳥巢因建於弱枝而傾覆。比喻處境極端危險。
【眼中有鐵】 比喻軍容整肅。語出《資治通鑒·陳世祖天嘉五年》:“春,正月,庚申朔,齊主登北城,軍容甚整。突厥咎周人曰:‘爾言齊亂,故來伐之:今齊人眼中亦有鐵,何可當耶!’” ...
請將 idioms.txt
讀進 R 成一個 character vector (每個元素皆為一筆成語, e.g. 【枕麹藉糟】 枕著酒,墊著酒糟。謂嗜酒,醉酒。
),並取出位於 【】
之內的詞彙。我們僅需要 4 個字組合而成的詞彙,不在此範圍內的請將其濾掉。請將最後的結果儲存於變數 idiom
:
# Write your code here
library(stringr)
<- readLines("idioms.txt")
idiom <- str_match(idiom, "【(\\w{4})】")[,2]
idiom <- idiom[!is.na(idiom)]
idiom
# 請勿更動下方程式碼
head(idiom)
length(idiom)
sum(is.na(idiom))
# Should print out:
#> [1] "澡身浴德" "枕麹藉糟" "正本清源" "認雞作鳳" "擊轂摩肩" "鳥覆危巢"
#> [1] 9705
#> [1] 0
#> [1] "澡身浴德" "枕麹藉糟" "正本清源" "認雞作鳳" "擊轂摩肩" "鳥覆危巢"
#> [1] 9705
#> [1] 0
readLines()
以將 idioms.txt
讀入str_match()
以取出 【】
內的成語中文裡面常常出現由四個字組合而成的表達方式,稱為四字格。四字格裡往往可以看到一些語言中的規律。 你的任務是完成下方的 classify()
。這個函數可以將輸入的四字格,依據其內部結構,分成 15 種類別:
<- function(idioms) {
classify # Write your code here
return(sapply(idioms, function(s) {
<- unlist(strsplit(s, ""))
chars <- chars[1]
a <- chars[2]
b <- chars[3]
c <- chars[4]
d # 4
if (a == b && b == c && c == d) return("AAAA")
# 3, 1
if (a == b && b == c) return("AAAB")
if (a == b && b == d) return("AABA")
if (a == c && c == d) return("ABAA")
if (b == c && c == d) return("ABBB")
# 2, 2
if (a == b && c == d) return("AABB")
if (a == c && b == d) return("ABAB")
if (a == d && b == c) return("ABBA")
# 2, 1, 1
if (a == b) return("AABC")
if (a == c) return("ABAC")
if (a == d) return("ABCA")
if (b == c) return("ABBC")
if (b == d) return("ABCB")
if (c == d) return("ABCC")
# 1, 1, 1, 1
return("ABCD")
USE.NAMES = FALSE))
},
}
##### 請勿更動下方程式碼 #####
<- c("念茲在茲", "騰雲駕霧", "清清白白", "一五一十", "防不勝防", "哈哈哈哈")
idioms classify(idioms)
<- strsplit("ABCC ABCA ABCB ABAC ABBC AABC AAAB AABA ABAA ABBB AABB ABAB ABBA", " ")[[1]]
test_pats paste(classify(test_pats), collapse = " ")
# Should print out:
#> [1] "ABCB" "ABCD" "AABB" "ABAC" "ABCA" "AAAA"
#> [1] "ABCC ABCA ABCB ABAC ABBC AABC AAAB AABA ABAA ABBB AABB ABAB ABBA"
#> [1] "ABCB" "ABCD" "AABB" "ABAC" "ABCA" "AAAA"
#> [1] "ABCC ABCA ABCB ABAC ABBC AABC AAAB AABA ABAA ABBB AABB ABAB ABBA"
請使用 classify()
, insert_spaces()
以及 tidyr::separate()
,將儲存在 idiom
中的成語變成一個 data frame 並儲存於變數 d
。這個 data frame 必須有 6 個變項 (資料類型皆為 character
):
idiom
: 本來儲存於變數 idiom
中的成語class
: 依據成語內部結構的分類結果first
: 該成語的第一個字second
: 該成語的第二個字third
: 該成語的第三個字fourth
: 該成語的第四個字# Write your code here
library(tidyr)
library(dplyr)
<- tidyr::tibble(idiom = idiom, class = classify(idiom), idiom_spaced = insert_spaces(idiom)) %>%
d ::separate(idiom_spaced, c("first", "second", "third", "fourth"), sep = " ")
tidyr##### 請勿更動下方程式碼 #####
%>% filter(class == "AABC") %>% tail()
d cat('\n')
%>% group_by(class) %>% summarise(count = n())
d # Should print out:
#> # A tibble: 6 x 6
#> idiom class first second third fourth
#> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 面面俱圓 AABC 面 面 俱 圓
#> 2 碌碌無能 AABC 碌 碌 無 能
#> 3 默默無言 AABC 默 默 無 言
#> 4 洋洋自得 AABC 洋 洋 自 得
#> 5 誇誇而談 AABC 誇 誇 而 談
#> 6 面面相覷 AABC 面 面 相 覷
#>
#> # A tibble: 15 x 2
#> class count
#> <chr> <int>
#> 1 AAAA 1
#> 2 AAAB 1
#> 3 AABA 1
#> 4 AABB 60
#> 5 AABC 78
#> 6 ABAA 1
#> 7 ABAB 1
#> 8 ABAC 278
#> 9 ABBA 1
#> 10 ABBB 1
#> 11 ABBC 1
#> 12 ABCA 20
#> 13 ABCB 44
#> 14 ABCC 43
#> 15 ABCD 9174
#> # A tibble: 6 x 6
#> idiom class first second third fourth
#> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 面面俱圓 AABC 面 面 俱 圓
#> 2 碌碌無能 AABC 碌 碌 無 能
#> 3 默默無言 AABC 默 默 無 言
#> 4 洋洋自得 AABC 洋 洋 自 得
#> 5 誇誇而談 AABC 誇 誇 而 談
#> 6 面面相覷 AABC 面 面 相 覷
#>
#> # A tibble: 15 x 2
#> class count
#> * <chr> <int>
#> 1 AAAA 1
#> 2 AAAB 1
#> 3 AABA 1
#> 4 AABB 60
#> 5 AABC 78
#> 6 ABAA 1
#> 7 ABAB 1
#> 8 ABAC 278
#> 9 ABBA 1
#> 10 ABBB 1
#> 11 ABBC 1
#> 12 ABCA 20
#> 13 ABCB 44
#> 14 ABCC 43
#> 15 ABCD 9174