Re: [筆記] R的字串處理

看板R_Language作者 (拒看低質媒體)時間11年前 (2013/05/22 00:26), 編輯推噓2(200)
留言2則, 2人參與, 最新討論串2/2 (看更多)
最近我發現另一個函數: `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
之前一直都不知道sprintf()這麼好用;推!
05/22 08:00, 1F

05/22 22:09, , 2F
有用
05/22 22:09, 2F
文章代碼(AID): #1Hcw0uBF (R_Language)
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 2 篇):
文章代碼(AID): #1Hcw0uBF (R_Language)