Re: [筆記] R的字串處理
最近我發現另一個函數: `sprintf`
比起`paste`, 已經會寫C 的版友可能會更喜歡這個函數。
基本用法:
```r
table_name <- "demo"
row_number <- 100
sprintf( "SELECT * FROM %s LIMIT %d" , table_name, row_number )
```
另外他也指定要印出的位數:
```r
a <- rnorm(1)
sprintf( "%4.2f %4.3f %4.4f", a, a, a)
```
如果不是一批字串向量要做處理的話,我比較喜歡這個函數。
寫起來比`paste`快
※ 引述《gsuper (Logit(odds))》之銘言:
: ※ [本文轉錄自 Statistics 看板 #1CA5vrBC ]
: 作者: gsuper (統計的巴比倫塔) 看板: Statistics
: 標題: [程式] R的字串處理
: 時間: Mon Jun 28 16:33:54 2010
: [軟體程式類別]:
: R
: [程式問題]:
: 資料處理
: [軟體熟悉度]:
: 中(3個月到1年)
: [問題敘述]:
: 最近常在處理字串
: 發現自己會的 function 很不夠用
: 想多學點 function
: 我列出一些我常用的
: 希望能拋磚引玉
: 請各位高手能教我一些高招
: [程式範例]:
: 前言 :
: R 的字串處理 ,
: 要小心注意 character , factor , numeric 這三種物件的誤轉換和混用
: factor 是一種很討厭的物件 ,
: 因為它在轉成數字和字串的時候 ,
: 常常會變成跟原本不一樣的東西 ,
: 建議資料處理的過程 ,
: 預設用 matrix 和 character 兩種而避免使用 data.frame
: ------------------------------------------------------------------
: 1.字串黏合
: paste ("A","B",sep="") ---->>> "AB"
: 2.字串切割
: strsplit("A.B",split=".",fixed=T) ---->>> "A" "B"
: 3.精確穩合
: x <- c("AB","AA")
: x %in% "AB" ---->>> TRUE FALSE
: 4.部份吻合 + (回傳 which)
: x <- c("AB","AA")
: grep("B",x) ---->>> 1
: grep("A",x) ---->>> 1 2
: grep("B",x,value=T) ---->>> "AB"
: grep("B",x,value=T,invert=T) ---->>> "AA"
: grep("C",x) ---->>> integer(0)
: #若目的是要找 index , 建議改用 grepl
: 4-2.部份吻合 + (回傳判斷式)
: x <- c("AB","AA")
: grepl("B",x) ---->>> TRUE FALSE
: 4-3.部份吻合 + (回傳位置) + (回傳??)
: x <- c("BBB","AAA","CCB")
: regexpr("B",x) ---->>> 1 -1 3 (第一次 "hit" 的位置)
: 1 -1 1 (有無 "hit")
: 5.子字串
: substr("human123456",start=1,stop=5) ---->>> "human"
: !!注意!! 4-3 的 regexpr
: 與這個 substr 結合起來 ,
: 在寫 網頁Parser 的時候很好用
: regexpr 能定義出 statr=多少
: 所謂的網頁Parser
: 就是你去下載某些 html 檔案
: 檢視原始碼
: 然後找出你需要的資料
: 再找出一些能 cut 的規則
: 用 strsplit 搭配 TR , TD 之類的字串去切出你要的資料
: 6.特定字元取代 (1st hit)
: x <- "AABB"
: sub("A",replacement="C",x) ---->>> "CABB"
: 6-2.全部特定字元取代 (global hit)
: x <- "AABB"
: gsub("A",replacement="C",x) ---->>> "CCBB"
: 7.計算字串長度
: ### 盡量別用這個 fuction
: x <- c("A","AAA","AAAAA")
: nchar(x) ---->>> 1 3 5
: nchar(as.factor(x)) ---->>> 1 1 1
: 8.多重字元(串)貼合 (矩陣內)
: x <- matrix(letters[1:6],2,3)
: apply(x,1,paste,collapse="") ---->>> "ace","bdf"
: apply(x,2,paste,collapse="") ---->>> "abc","def"
: 9. 字元反轉
: x <- c("A B","*.")
: sapply(lapply(strsplit(as.character(x), NULL), rev), paste, collapse="")
: [1] "B A" ".*"
: 10.字元檢查
: x <- c("A B","*.")
: unique(unlist(strsplit(as.character(x),split="",fixed=T)))
: [1] "A" " " "B" "*" "."
: -----------------------------------------------------------
: Regular expression : 字串模糊比對 , 或特定字母排列模式的抓取
: 在R內
: 基本上分成3種
: Basic regular expression (BRE) --> extended = FALSE
: Extended regularexpression (ERE) --> extended = TRUE (預設)
: perl-like (perl) --> perl = TRUE
: 雙冒號代表我測試過且成功
: 單冒號代表網路上抓下來或是測試失敗
: --------------------------------------------------------------
: 通用部分
: {,}
: * :: {0, } 至少出現0次, 最多無限多次
: + :: {1, } 1 無限多次
: ? :: {0,1} 0 1
: [Aa] :: A 或 a
: [^1-9] :: not 1:9
: [1-9] :: 1:9
: [a-z] :: a b c ... z
: [A-Z] :: A B C ... Z
: [a-zA-Z] :: 所有英文字母
: [W-z] :: WXYZabc....z
: [w-Z] :: 不可使用!
: (AB) :: 括號一次收集多個字元 ### 一種延伸字串的寫法
: 舉例 :
: x <- c("company","companies",)
: 可以用以下兩種寫法
: 1. grep("[company|companies]",x)
: 2. grep("compan(y|ies)",x)
: 第二種在大資料的時候會比較快
: $ :: 字尾限定
: ^ :: 字首限定
: | :: "ABC|EFG" --> grep("ABC"or"DEF",x)
: . :: 任意字元
: -----------------------------------------------------
: ERE , extended = TRUE
: digit (數字)
: \\d :: [0-9]
: \\D :: [^0-9]
: [[:digit:]] :: 同上
: [^[:digit:]] :: 同上
: blank (空白)
: \\s :: 能切開 " " 或 "\t"
: \\S :: 切開非空白及 tab 的字元
: [[:blank:]] :: 同上
: [^[:blank:]] :: 同上
: AlphaBet + Digit (正常字元)
: \\w :: [0-9a-zA-Z]
: \\W :: [^0-9a-zA-Z]
: [[:alnum:]] :: 同上
: [^[:alnum:]] :: 同上
: AlphaBet (英文字元)
: [[:alpha:]] :: 同上
: [^[:alpha:]] :: 同上
: 特殊符號
: [[:punct:]] :: ! " # $ % & ' ( ) * + , - .
: / : ; < = > ? @ [ \ ] ^ _ ` { | } ~
: [^[:punct:]] :: 英文字 , 數字 (注意! , \t 和 \n 都會被切掉)
: 注意 ! 正斜線這個符號很容易與其他 regular expr 混淆
: 必須仔細檢查 "\" 存在的字串
: 可印符號
: [[:print]] :: 所有字元 (數字,字母,特殊符號,空白)
: \n , \t , \001 除外
: 16進位字元
: [[:xdigit:]] :: 16進位有關英文或數字
: [0-9a-fA-F]
: 大小寫英文字元
: [[:upper:]] :: 大寫英文字元 [A-Z]
: [^[:upper:]] :: 非大寫 [^A-Z]
: [[:lower:]] :: 小寫 [a-z]
: [^[:lower:]] :: ^[a-z]
: 注意 "\t" 還是會被留下來
: 空白和換行等
: [[:space:]] :: " " , \t , \n , \f , \r
: (\f : 換行但不回到行頭)
: (\r : 回到行頭並消除此行內所有的文字)
: P.S. 這兩種不常用,當豆知識即可
: [[:graph:]] :: [A-Za-z0-9]再加[["punct"]]
: ----------------------------------------------------------
: perl = TRUE
: \\w : [A-Za-z0-9_]
: \\W : [^A-Za-z0-9_]
: \\s : [\t\n\r\f]
: \\S : [^\t\n\r\f]
: \\d : [0-9]
: \\D : [^0-9]
: ----------------------------------------------------------
: regular expression 工事中 (未完)
: 感覺這篇被我當筆記來用了
: reference:
: 1. http://www.rtfiber.com.tw/~changyj/
: 2. http://www.stat.psu.edu/~dhunter/R/html/base/html/regex.html
: ----------------------------------------------------------
: 大小寫切換
: TRUTH <- c("Abc","ABC")
: a <- gsub("(\\w)","\\L\\1",TRUTH,perl=TRUE) ---> "abc","abc"
: b <- gsub("^(\\w)","\\U\\1",a,perl=TRUE) ---> "Abc","Abc"
: 同上 , 非常神秘的 Bug !?
: T123 <- c("Tgfbr1","Cd320","Ndrg3","Aldoa","Bckdk","Tmed3","Hfe2")
: > gsub( "(\\w)", "\\L\\1" , T123 , perl=T)
: [1] "LTLgLfLbLrL1" "LCLdL3L2L0" "LNLdLrLgL3"
: [4] "LALlLdLoLa" "LBLcLkLdLk" "LTLmLeLdL3"
: [7] "LHLfLeL2"
: > gsub( "(\\w)", "\\L\\1" , T123 , perl=TRUE)
: [1] "tgfbr1" "cd320" "ndrg3" "aldoa" "bckdk" "tmed3"
: [7] "hfe2"
: ---------------------------------------
: 消除多餘空白
: > x <- "Hey! Apple "
: > gsub(" {2,}","",x)
: [1] "Hey! Apple" ### 容忍一個空白 , 但兩個以上至無限大則消除
: ---------------------------------------
: 在處理混合字串與數字的資料矩陣的時候
: 常常需要在 data.frame 和 matrix 之間切換
: 有時候會字串會被一些預設的空白字元夾住
: ex:
: "1" , "15" , "333"
: 經過轉換以後
: " 1" , " 15" , "333" (fit 最長字串的長度)
: > DATA <- gsub("^ *| *$",as.matrix(DATA))
: ---------------------------------------
: ### 一些參考的 pattern
: 1. "^\\d+$" ### 純數字的欄位 ###
: 2. "^ *| *$" ### 字首字尾的空白(搭配 gsub) ###
: 3. "^[0][\\.]{0,1}[0]*$" ### "0" "0.0" "0.00" "0.000" "0.0000" ,
: bug 是 "0." "00"
: ####################################################################
: 放一些 linux 下的好用指令
: 光用 R 來做字串處理不夠用
: 原因在於若處理的檔案太大
: 光是讀進 R 就累死人
: 這邊主要是應用在檔案減肥
: 文字檔案
: rs123\t0|1:0000\tAAAA
: rs456\t1|0:0000\tBBBB
: ###################
: 橫向
: grep [-w : word]
: [-f : 給 pattern file]
: [-F : 精確比對] ### 若要搜尋固定字串 , -F必下 (快超多)
: 1. cat 文字檔案|grep -w 'rs' ### 沒東西
: 2. cat 文字檔案|grep -w -F 'rs123' ### 出第一行
: 3. car 文字檔案|grep -w '^rs.*$' ### 二行皆出
: ###################
: 縱向
: cut [-d : 用tab切開會是3個column的矩陣]
: 1. cut -d'\t' -f1,2 原檔 > 新檔 ### 留下 1 and 2 columns
: ###################
: 橫向
: sed
: 1. sed -n '6,$p' 原檔 > 新檔 ### 從第六行開始 , print 至尾行
: ### 或可理解成, 把 1~5行切掉
: 2. sed 's/:\S*/HAHA/g' 原檔 > 新檔 ### s=取代 , g=global
: ### 把紅色的正規 pattern 取代成綠色
: ###################
: 當檔案有 10000000 rows , 讀不進 R 怎辦?
: 就算讀進 R , 資料太大一直 SWAP 電腦動不了怎麼辦?
: 經過一番苦戰
: 我建議以下的思考方式
: 0. 先透過上述方式
: 直接在終端機把檔案減肥
: 1. 檔案列數 <- system("wc -l 檔案",intern=TRUE)
: LOOP <- ceiling(檔案列數 / 5000)
: for(g in 1:LOOP) ### 用while可省前兩行
: { tmp <- read.table(檔案,skip=5000*(g-1),nrow=5000) ### 但我只熟 for
: expr(中間的各種處理)
: write.table(tmp,g)
: Sys.sleep(5) ### 給一點時間讓電腦回氣
: }
: 2. system("cat 小檔案1 小檔案2 小檔案3 .... > 總檔案") ### 檔案 rbind()
: 雖然不是最快的方法
: 但 Over night 是一定可以把檔案處理完的
: 以上
--
歡迎加入 Taiwan R User Group : http://www.facebook.com/Tw.R.User
我們每週一都有在「政大公企中心(台北市金華街187號)西樓WB05」
舉辦Machine Learning / Data Mining Monday:
報名 http://www.meetup.com/Taiwan-R/
聚會影片 https://www.youtube.com/user/TWuseRGroup
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 118.166.97.9
推
05/22 08:00, , 1F
05/22 08:00, 1F
推
05/22 22:09, , 2F
05/22 22:09, 2F
討論串 (同標題文章)
R_Language 近期熱門文章
PTT數位生活區 即時熱門文章