請寫一個函數 insert_spaces()
,用來將傳入的字串的各個字元之間插入空白。此函數會在後面的題目用到。
要求:
stringr
以及 base R 的 grep
系列函數 (見 ?grep
內出現的函數)strsplit()
, sapply()
與 paste()
<- function(x) {
insert_spaces # Write your code here
<- sapply(x, function(words) {
x <- strsplit(words, split = "")
splits <- unlist(splits)
vectors <- paste(vectors, collapse = " ")
result return(result)
})return(as.vector(x))
}
#### 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")
idioms <- str_match(idioms, "【\\w{4}】")
idiom <- str_remove(idiom, "(【)")
idiom <- str_remove(idiom, "(】)")
idiom <- as.vector(idiom)
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
<- sapply(idioms, function(words) {
idioms <- strsplit(words, split = "")
splits
<- c()
pattern for (word in splits[[1]]) {
if (!(word %in% pattern)) {
<- c(pattern, word)
pattern
}
}names(pattern) <- LETTERS[1:length(pattern)]
<- sapply(splits[[1]], function(char) {
symbol return((names(pattern[!is.na((str_match(char, pattern)))])))
})
<- as.vector(paste(symbol, collapse=""))
symbols return(symbols)
})
return(as.vector(idioms))
}
##### 請勿更動下方程式碼 #####
<- 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(dplyr)
library(tidyr)
<- data.frame(idiom = idiom, class = classify(idiom), sep_idiom = insert_spaces(idiom))
d <- d %>% separate(sep_idiom, c("first", "second", "third", "fourth"), sep = " ")
d ##### 請勿更動下方程式碼 #####
%>% 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
#> idiom class first second third fourth
#> 73 面面俱圓 AABC 面 面 俱 圓
#> 74 碌碌無能 AABC 碌 碌 無 能
#> 75 默默無言 AABC 默 默 無 言
#> 76 洋洋自得 AABC 洋 洋 自 得
#> 77 誇誇而談 AABC 誇 誇 而 談
#> 78 面面相覷 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