作者Wush978 (拒看低质媒体)
看板R_Language
标题Re: [笔记] R的字串处理
时间Wed May 22 00:26:30 2013
最近我发现另一个函数: `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
1F:推 diplazium:之前一直都不知道sprintf()这麽好用;推! 05/22 08:00
2F:推 MIZUYAMA:有用 05/22 22:09