R語言-字符串處理函數


R語言中的字符串處理函數


內容概覽

  盡管R是一門以數值向量和矩陣為核心的統計語言,但字符串有時候也會在數據分析中占到相當大的份量。

  R語言是一個擅長處理數據的語言,但是也不可避免的需要處理一些字符串(文本數據)。如何高效地處理文本數據,將看似雜亂無章的數據整理成可以進行統計分析的規則數據,是『數據玩家』必備的一項重要技能。

  在編程語言里,文本處理絕對是一大熱門,作為數據統計分析最熱門的R語言,雖然處理方法沒有其他的文本的編程語言豐富,但其處理文本的能力也是非常實用的。特別是在文本數據挖掘日趨重要的背景下,在數據預處理階段你需要熟練的操作字符串對象去處理文本數據。如果你擅長其它的處理軟件,比如Python,可以讓它來負責前期的臟活,當然你也可以直接用R進行處理。

  今天,我們要學習的『正則表達式』和『字符處理函數』將助你成為點石成金的數據魔法師。下面介紹在R語言里面常用的文本處理函數和方法。

  • 獲取字符串長度:nchar()能夠獲取字符串的長度,它也支持字符串向量操作。注意它和length()的結果是有區別的。

  • 字符串粘合:paste()負責將若干個字符串相連結,返回成單獨的字符串。其優點在於,就算有的處理對象不是字符型也能自動轉為字符型。

  • 字符串分割:strsplit()負責將字符串按照某種分割形式將其進行划分,它正是paste()的逆操作。

  • 字符串截取:substr()能對給定的字符串對象取出子集,其參數是子集所處的起始和終止位置。

  • 字符串替代:gsub()負責搜索字符串的特定表達式,並用新的內容加以替代。sub()函數是類似的,但只替代第一個發現結果。

  • 字符串匹配:grep()負責搜索給定字符串對象中特定表達式 ,並返回其位置索引。grepl()函數與之類似,但其后面的"l"則意味着返回的將是邏輯值。

  • 字符(串)的格式化(定制)輸出:R中將字符或字符串按照一定的格式和要求輸出。

      字符串分割函數:strsplit()
      字符串連接函數:paste()及paste0()
      計算字符串長度:nchar()及length()
      字符串截取函數:substr()及substring()
      字符串替換函數:chartr()、sub()及gsub()
      字符串匹配函數:grep()及grepl()
      大小寫轉換函數:toupper()、tolower()及casefold()
      字符(串)的格式化(定制)輸出函數:sprintf()、sink()、cat()、print()、strtrim()、strwrap()
    

字符串函數參數詳解及示例


1. 字符串分割函數:strsplit()

  strsplit()是一個拆分函數,該函數可以使用正則表達式進行匹配拆分。

    其命令形式為:strsplit(x, split, fixed= F, perl= F, useBytes= F)

  在R里面,strsplit一般用來進行字符串分割操作,我們先來看下strsplit函數有哪些選項:x、split、fixed、perl這四個選項是我們會經常用到的。

  • 參數x為字符串格式向量,函數依次對向量的每個元素進行拆分

  • 參數split為拆分位置的字串向量,即在哪個字串處開始拆分;該參數默認是正則表達式匹配;若設置fixed= T則表示是用普通文本匹配或者正則表達式的精確匹配。用普通文本來匹配的運算速度要快些。

  • 參數perl的設置和perl的版本有關,表示可以使用perl語言里面的正則表達式。如果正則表達式過長,則可以考慮使用perl的正則來提高運算速度。

  • 參數useBytes表示是否逐字節進行匹配,默認為FALSE,表示是按字符匹配而不是按字節進行匹配。

  • Example1

      ### strsplit()函數用於字符串分割,其中split是分割參數。所得結果以默認以list形式展示。
      ### 首先x和split是兩個必須的選項:
      > x = "character vector, each element of which is to be split. Other inputs, including a factor, will give an error."
      > x
      [1] "character vector, each element of which is to be split. Other inputs, including a factor, will give an error."
      > strsplit(x,split = "\\s+")
      [[1]]
       [1] "character" "vector,"   "each"      "element"   "of"        "which"     "is"        "to"        "be"        "split."    "Other"    
      [12] "inputs,"   "including" "a"         "factor,"   "will"      "give"      "an"        "error."   
      
      > strsplit(x,split = " ")
      [[1]]
       [1] "character" "vector,"   "each"      "element"   "of"        "which"     "is"        "to"        "be"        "split."    "Other"    
      [12] "inputs,"   "including" "a"         "factor,"   "will"      "give"      "an"        "error."   
      
      > strsplit(x,split = "")
      [[1]]
        [1] "c" "h" "a" "r" "a" "c" "t" "e" "r" " " "v" "e" "c" "t" "o" "r" "," " " "e" "a" "c" "h" " " "e" "l" "e" "m" "e" "n" "t" " " "o" "f" " " "w"
       [36] "h" "i" "c" "h" " " "i" "s" " " "t" "o" " " "b" "e" " " "s" "p" "l" "i" "t" "." " " "O" "t" "h" "e" "r" " " "i" "n" "p" "u" "t" "s" "," " "
       [71] "i" "n" "c" "l" "u" "d" "i" "n" "g" " " "a" " " "f" "a" "c" "t" "o" "r" "," " " "w" "i" "l" "l" " " "g" "i" "v" "e" " " "a" "n" " " "e" "r"
      [106] "r" "o" "r" "."
    
    
      ###在上面的例子中我們可以看到,我們對split選項設置了三個不同的參數,第一個是`\\s+`,第二個是一個空格,第三個一個空字符。
      ###第一個參數`\\s+`和第二個參數空格達到了相同的效果,都是把x字符串按照空白進行分割。那個這里為什么是`\\s+`呢?相信對正則表達式有一點了解的同學一定會知道`\s+`是什么意思。`\s+`是表示匹配一個或一個以上的空白字符,包括空格、制表符和換行符等。這里的第一個`\` 是用來轉義第二個`\` 符號的。
      ###那么第三個參數里面,我們設置 `split=""` 又是什么意思呢?當設置為空字符的時候,`strsplit` 函數會把字符串按照字符一個個進行分割。
    
  • Example2

      ### strsplit默認支持正則表達式
      ###在上面的例子中我們也可以看到strsplit默認是支持正則表達式的。
      ###那么如果我要不支持正則表達式強行按照固定字符匹配怎么辦呢?除了我們用更加高級的正則表達式達到這一目的我們還可以通過設定fixed參數來達到目的:
    
      > x = "asdas\\sasdasd"
      > x
      [1] "asdas\\sasdasd"
      > strsplit(x,split = "\\s")
      [[1]]
      [1] "asdas\\sasdasd"
      
      > strsplit(x,split = "\\s",fixed = T)
      [[1]]
      [1] "asdas"  "asdasd"
      
      > strsplit(x,split = "\s")
      Error: '\s' is an unrecognized escape in character string starting ""\s"
    
      ###比如這里的 x 字符串,它帶有兩個`\`,我要以`\\s`來進行分割。如果我直接設定`split='\\s'`參數時,`strsplit`函數無法正確的分割字符串,但是當我加了`fixed=T`參數后,`strsplit`函數可以正確分割這些字符串。
      ###在strsplit函數中,是默認支持正則表達式的,我們可以通過設置perl來支持使用perl兼容的正則表達式。也可以通過fixed來設置不支持正則表達式,而且fixed選項擁有比perl更高的優先級。
    
  • Example3

      ###fixed為TRUE表示精確匹配,否則表示可以使用正則表達式另外需要說明一點的是:直接使用split函數得到的結果是一個列表,如果希望得到一個向量,可以使用 unlist() 函數。
      # 由於split是正則表達式,所以在切割包含.的字符串的時候萬分小心
      unlist(strsplit("a.b.c", "."))
      ## [1] "" "" "" "" ""
      ## following are right answers
      unlist(strsplit("a.b.c", "[.]"))
      ## [1] "a" "b" "c"
      unlist(strsplit("a.b.c", ".", fixed = TRUE))
      unlist(strsplit("a.b.c","\\."))
      ## 編寫逆寫字符串
      ## a useful function: rev() for strings
      strReverse <- function(x)
              sapply(lapply(strsplit(x, NULL), rev), paste, collapse = "")
      strReverse(c("abc", "Statistics"))
      
      ## 得到R核心團隊成員的名First Name
      ## get the first names of the members of R-core
      a <- readLines(file.path(R.home("doc"),"AUTHORS"))[-(1:8)]
      a <- a[(0:2)-length(a)]
      (a <- sub(" .*","", a))
      # and reverse them
      strReverse(a)
      # 注意:最后一個空字符串將會被忽略
      strsplit(paste(c("", "a", ""), collapse="#"), split="#")[[1]]
      # [1] ""  "a"
      
      # split=NULL逐個切割字符串
      strsplit("abcde",NULL)
    

2. 字符串連接函數:paste() 及 paste0()

  主要參數: paste(..., sep = " ", collapse = NULL)

       paste0(..., collapse = NULL)

  paste()函數用於字符串連接,其中 sep 負責兩組字符串間的連接; collapse 負責一組字符串內部的連接,常常在一些作圖的標題中看到paste的使用。

  • Example1

      ### paste()函數可以將多個字符型向量連接成一個向量。如果要將一個不同類型的向量連接起來,這個向量首先會被轉換成字符型向量。
    
      > x <- c("a","b", "c", "d", "e")
      > y <- c("A", "B", "C", "D","E")
      > paste(x, y)
      [1] "a A" "b B" "c C" "d D" "e E"
    
  • Example2

      ### 在默認情況下,向量的值之間使用空格進行分隔的。 若想使用其他分隔符,可以使用sep參數進行設置,例如:
    
      > paste(x, y, sep = "-")
      [1] "a-A" "b-B" "c-C" "d-D" "e-E"
      > paste(x, y, sep = "")
      [1] "aA" "bB" "cC" "dD" "eE"
      
      > paste(letters[1:6],1:6,sep="-")
      [1] "a-1" "b-2" "c-3" "d-4" "e-5" "f-6"
    
  • Example3

      ### 若將返回的所有向量都連成一個字符串,那么則需要collapse參數來指定這些值之間的連接符。例如:
    
      > paste(x, y, sep = "-", collapse = "#")
      [1] "a-A#b-B#c-C#d-D#e-E"
    
      > paste(letters[1:6],1:6,sep="-",collapse=";")
      [1] "a-1;b-2;c-3;d-4;e-5;f-6"
      
      > nth <- paste0(1:12, c("st", "nd", "rd", rep("th", 9)))
      > paste(month.abb, "is the", nth, "month of the year.", sep = "_*_")
      [1] "Jan_*_is the_*_1st_*_month of the year."  "Feb_*_is the_*_2nd_*_month of the year."
      [3] "Mar_*_is the_*_3rd_*_month of the year."  "Apr_*_is the_*_4th_*_month of the year."
      [5] "May_*_is the_*_5th_*_month of the year."  "Jun_*_is the_*_6th_*_month of the year."
      [7] "Jul_*_is the_*_7th_*_month of the year."  "Aug_*_is the_*_8th_*_month of the year."
      [9] "Sep_*_is the_*_9th_*_month of the year."  "Oct_*_is the_*_10th_*_month of the year."
      [11] "Nov_*_is the_*_11th_*_month of the year." "Dec_*_is the_*_12th_*_month of the year."
    
  • Example4

      ### paste()在不指定分割符的情況下,默認分割符是空格;paste0()在不指定分割符的情況下,默認分割符是空。
    
      # 默認以空格隔開
      paste("Hello","world")
      [1] "Hello world"
      
      # 沒有空格
      paste0("Hello","world")
      [1] "Helloworld"
      
      # 指定分割符
      paste("abc", "efg", "hijk", sep = "-")
      [1] "abc-efg-hijk"
      
      # 分別對向量的每一個元素進行連接
      paste0("A", 1:6, sep = "")
      [1] "A1" "A2" "A3" "A4" "A5" "A6"
      
      # collapse參數:每一個元素操作之后,再把向量的每一個元素進行連接
      paste0("A", 1:6, sep = "",collapse = "-")
      [1] "A1-A2-A3-A4-A5-A6"
    

3. 計算字符串長度:nchar()及length()

  nchar()返回字符串的長度,取字符數量的函數。length與nchar不同,length是取向量的長度(nchar用於計算 x 中的字符數量,length函數返回 x 的集合長度)。

  用法:nchar(x, type = "chars", allowNA = FALSE, keepNA = FALSE)

  nzchar(x)用於判斷一個變量的長度是否為0。

  需要注意的是,對於缺失值NA,nzchar()的結果為TRUE,而函數nchar()的返回結果為2。所以在對字符串進行測量之前,最好先使用is.na()函數判斷一下是否是NA值。

  • Example

      x <- c("asfef", "qwerty", "yuiop[", "b", "stuff.blah.yech")
      > nchar(x)
      # 5  6  6  1 15
      
      #現R語言設定為NA長度為2
      > nchar(NA) 
      ## [1] 2
      > nzchar(NA)
      [1] TRUE
      > x <- ''
      > nzchar(x)
      [1] FALSE
      > nchar("你好",type="chars")   #默認情況
      ## [1] 2
      > nchar("你好",type="bytes")   #每個中文字符占2個bytes
      ## [1] 4
      > nchar("你好",type="width")
      ## [1] 4
    
      > m<-"who wins 123"
      > nchar(m)
      [1] 12
      > length(m)
      [1] 1
      
      # nchar表示字符串中的字符的個數
      > nchar("abcd")
      [1] 4
      
      # length表示向量中元素的個數
      > length("abcd")
      [1] 1
      > length(c("hello", "world"))
      [1] 2
      > length("")  #雖然字符為空,但是它仍然是一個元素。
      [1] 1
    

4. 字符串截取函數:substr();substring()

  substr()函數和substring()函數是截取字符串最常用的函數,兩個函數功能方面是一樣的,只是其中參數設置不同。

  substr()函數:必須設置參數start和stop,如果缺少將出錯。

  substring()函數:可以只設置first參數,last參數若不設置,則默認為1000000L,通常是指字符串的最大長度。

  substr(x, start, stop)

  substring(text, first, last = 1000000L)

  substr(x, start, stop) <- value

  substring(text, first, last = 1000000L) <- value

  • Example1

      ### substr能夠提取或替換一個字符向量中的子串或替換子字符串
      > substr('abcdef',2,4)
      [1] "bcd"
      > substr("abcdef", 2, 4)   #兩種表達方式等價
      [1] "bcd"
      > x <- "abcdef"
      > substr(x, 1, 1) <- "ccc"
      > x
      [1] "cbcdef"
      > x <- "abcdef"
      > substr(x, 1, 1) <- ""
      > x
      [1] "abcdef"
      > x <- "abcdef"
      > substr(x, 1, 1) <- " "
      > x
      [1] " bcdef"
      > #如果start大於字符串長度,則返回""
      > x <- c("asfef", "qwerty", "yuiop[", "b", "stuff.blah.yech")
      > substr(x, 2, 5)
      [1] "sfef" "wert" "uiop" ""     "tuff"
      
      > m<-"who wins 123"
      > substr(m,1,8)
      [1] "who wins"
      > substr(m,1,3)<-"Tom"
      > m
      [1] "Tom wins 123"
    
  • Example2

      ### substring函數則可以對字符串向量進行提取或替換
    
      > substring('abcdef', 1, 6)
      [1] "abcdef"
      
      > substring('abcdef', 1:6, 6)
      [1] "abcdef" "bcdef"  "cdef"  
      [4] "def"    "ef"     "f"  
      
      ### 切割字符串另類方法,但速度不如strsplit
      >substring('abcdef',1:6,1:6)
      [1] "a" "b" "c" "d" "e" "f"
    
      ### 替換字符串向量中的部分元素
      > x <- c("asfef", "qwerty", "yuiop[", "b", "stuff.blah.yech")
      ### 由於x長度為5,賦值向量會循環補齊,相當於 c("..", "+++", "..", "+++", "..")
      ### substring(x, 2) <- c("..", "+++", "..", "+++", "..")
      > substring(x, 2) <- c("..", "+++")
      > x
      [1] "a..ef"           "q+++ty"         
      [3] "y..op["          "b"              
      [5] "s..ff.blah.yech"
    
  • Example3

      ### 兩者的一些區別:substr返回的字串個數等於第一個參數的長度,而substring返回字串個數等於三個參數中最長向量長度,短向量循環使用。
    
      > substr("abcdef", 1:6, 1:6) 
      [1] "a"
      
      #注意還有一個substring函數,效果就不一樣了:
      > substring("abcdef",1:6,1:6) 
      [1] "a" "b" "c" "d" "e" "f"
      
      #等價於:substr("123456789", 2, 4)
      > substr("123456789", c(2, 3), c(4, 5, 6))  
      [1] "234"
      
      #最長的向量長度為3,其它向量都循環補齊
      > substring("123456789", c(2, 3), c(4,5,6)) 
      [1] "234"   "345"   "23456"
    

5. 字符串替換函數:chartr()、sub()及gsub()

  chartr()函數:將原有字符串中特定字符替換成所需要的字符。其中參數old 表示原有字符串中內容;new 表示替換后的字符內容。

  chartr (old,new,x),chartr-將對象中舊的字符用新的字符替代。

  這種功能和shell里面的rename有點類似,但old的字符數不能大於new,new字符數大於old的字符也將會被忽略,相當於重命名的意思。不同於rename的是chartr不能隨意的替換字符串,用起來也有一定的局限性。

  • Example1

      > m<-"who wins 123"
      > chartr("w","W",m)
      [1] "Who Wins 123"
    
      > chartr(old="a", new="c", x="a123")
      [1] "c123"
      
      > chartr(old="a", new="A", x="data")
      [1] "dAtA"
    
  • Example2

      ### gsub() 替換匹配到的全部;sub() 替換匹配到的第一個。
      ### sub()函數可以用來替換字符串。需要注意的是我們需要設置一個變量來接受這個替換操作后的字符,sub()函數不會對原變量進行操作。
    
      ######正則表達式解釋######
      ## /^\d+$/ 是正則表達式
      ## ^和$用來匹配位置:^表示行首,$表示行尾
      ## \d表示數字,即0-9
      ## +表示重復1次以上
      ## 綜合起來,/^\d+$/ 這個正則表達式就是匹配一整行1個以上的數字
      ## /^\d+$/ 就相當於 $_=~/^\d+$/ 
      ## 就是對默認變量$_進行匹配,匹配成功就返回'真',否則就返回'假'
      ## !/^\d+$/ 就是對~/^\d+$/返回的布爾值取反
      ######正則表達式解釋######
      > str <- "Now is the time      "
      > sub(" +$", " 12:00", str)  ## spaces only
      [1] "Now is the time 12:00"
      ##幾種錯誤寫法##
      > sub(" +s", " 12:00", str)
      [1] "Now is the time      "
      > sub(" ", " 12:00", str)
      [1] "Now 12:00is the time      "
      > sub("     ", " 12:00", str)
      [1] "Now is the time 12:00 "
      
      # 將b替換為B
      > gsub(pattern = "b", replacement = "B", x = "baby")
      [1] "BaBy"
      > gsub(pattern = "b", replacement = "B", x = c("abcb", "boy", "baby"))
      [1] "aBcB" "Boy"  "BaBy"
      # 只替換第一個b
      > sub(pattern = "b", replacement = "B", x = "baby")
      [1] "Baby"
      > sub(pattern = "b", replacement = "B", x = c("abcb", "baby"))
      [1] "aBcb" "Baby"
    

6. 字符串匹配函數:grep()及grepl()

  其表達式為:

  grep(pattern, x, ignore.case = FALSE, perl = FALSE, value = FALSE,fixed = FALSE, useBytes = FALSE, invert = FALSE)

  grepl(pattern, x, ignore.case = FALSE, perl = FALSE,fixed = FALSE, useBytes = FALSE)

  可以理解為搜索字符向量中匹配參數pattern的模型,fixed的邏輯值決定將pattern視為正則表達式或一個文本字符串,若fixed=TURE,則視pattern為文本字符串(精確匹配);fixed=FALSE,則視之為正則表達式,正則表達式則相當於一種條件,函數返回匹配值的下標;perl=TURE,使用perl風格的正則表達式;value則決定返回的類型是匹配值的下標還是匹配的值。

  • Example1

      > x = "Hello World"
      > grep(pattern = "Hello",x = x)
      [1] 1
      > grep(pattern = "l",x = x)
      [1] 1
      > grepl(pattern = "l",x = x)
      [1] TRUE
    
  • Example2

      ### grep和grepl的區別在於grep返回的是匹配正確的字符串在 x 向量中的元素下標。而grepl返回的則是邏輯變量TRUE和FALSE。
      ### 如果我們想要返回匹配正確字符的值要怎么辦呢?我們可以通過設置grep中的value=T來達到目的。如:
      
      > x = c("Hello","Bye","Hi")
      > grep(pattern = "l",x = x,value = T)
      [1] "Hello"
      > grep(pattern = "H",x = x,value = T)
      [1] "Hello" "Hi"   
      > grep(pattern = "H",x = x,value = F)
      [1] 1 3
    
  • Example3

      ### 在grep和grepl中,fixed和perl兩個參數的用法跟strsplit中的用法是一致的。
      ### 正則表達式中,“[a-z]”就表示匹配a~z,所以[a-f]表示匹配正則表達式前面6個
      > grep("[a-f]",letters)      
      [1] 1 2 3 4 5 6 
    
  • Example4

      ### 使用fixed=T,因為我們匹配的類型是精確匹配,so
      >grep("[a-f]",letters,fixed=T)      
      integer(0)    #精確匹配中,[a-f]代表的是字符,所以就不能匹配到
    
  • Example5

      ### 匹配的 fixed 默認為F,這也提示我們應盡量的去使用正則表達式去匹配
      > txt <- c("arm","foot","lefroo", "bafoobar")
      > grep("foo",txt)
      [1] 2 4
    
  • Example6

      ### ignore.case 決定匹配是否對大小寫敏感,為了達到精確匹配,默認為對大小寫敏感;你完全可以設置不敏感,比如一些開頭字母大寫的問題。例如:
      
      > grep("Foo",txt)
      integer(0)
      
      > grep("Foo",txt,ignore.case=TRUE)
      [1] 2 4
      
      > grep("Foo",txt,ignore.case=T,value=T)
      [1] "foot"     "bafoobar"
    
  • Example7

      ### invert 參數非常實用,它決定返回的的是匹配值還是非匹配值,往往我們要的結果就是非匹配值,例如在眾多的郵件中根據內容不含”xxx”進行保留。
    
      > grep("Foo",txt,ignore.case=T,invert=T,value=T)
      [1] "arm"    "lefroo"
    
  • Example8

      ### grepl函數與grep函數不同的地方在於返回的形式是否為布爾值(是 true 或 false 中的一個),grepl返回TURE或者FALSE,而grep函數返回匹配值下標或者匹配值本身,使用什么函數要看我們的需要。
    
      > grepl("Foo",txt,ignore.case=T)
      [1] FALSE  TURE FALSE  TURE
    

7. 大小寫替換函數:toupper()、tolower()、casefold()

  toupper()函數:將字符串統一轉換為大寫。

  tolower()函數:將字符串統一轉換為小寫。

  casefold()函數:根據參數轉換大小寫。

  tolower(x)

  toupper(x)

  casefold(x, upper = FALSE)

  chartr(old, new, x)

  • Example

      ### 這兩個函數就不用多介紹了,按字面意思就是把對象轉換成大寫或小寫,應用於全部的對象,例如:
    
      >toupper("abc")
      [1]"ABC"
      >tolower("ABC")
      [1]"abc"
      >x<-c("My","First","Trip")
      >tolower(x)
      [1] "my" "first" "trip"
      
      > casefold('ABDATA', upper = FALSE)
      [1] "abdata"
      > casefold('baorui', upper = FALSE)
      [1] "baorui"
      > casefold('baorui', upper = TRUE)
      [1] "BAORUI"
    
      # 這里這只提供全部應用的大小寫轉換,部分轉換可以參照函數chartr()。
      chartr(old, new, x)
    

8. 字符(串)的格式化(定制)輸出

  • 字符格式化輸出

      使用%s替代字符變量
      a <- "string"
      sprintf("This is where a %s goes.", a)
      # "This is where a string goes."
      
      # 使用%d替代整數
      x <- 8
      sprintf("Regular:%d", x)
      # "Regular:8"
      # Can print to take some number of characters, leading with spaces.
      sprintf("Leading spaces:%4d", x)
      # "Leading spaces:   8"
      # Can also lead with zeros instead.
      sprintf("Leading zeros:%04d", x)
      #"Leading zeros:0008:"
      
      #使用%f替代浮點數
      # %m.nf m為輸出字符寬度,即最小包含的字符量。如果字符串沒有達到m長度,那么可以通過補0或者空格,n表示小數的精度
      sprintf("%f", pi)         # "3.141593"
      sprintf("%.3f", pi)       # "3.142"
      sprintf("%1.0f", pi)      # "3"
      sprintf("%5.1f", pi)      # "  3.1"
      sprintf("%05.1f", pi)     # "003.1"
      sprintf("%+f", pi)        # "+3.141593"
      sprintf("% f", pi)        # " 3.141593"
      sprintf("%-10f", pi)      # "3.141593  "   (left justified)
      sprintf("%e", pi)         #"3.141593e+00"
      sprintf("%E", pi)         # "3.141593E+00"
      sprintf("%g", pi)         # "3.14159"
      sprintf("%g",   1e6 * pi) # "3.14159e+06"  (exponential)
      sprintf("%.9g", 1e6 * pi) # "3141592.65"   ("fixed")
      sprintf("%G", 1e-6 * pi)  # "3.14159E-06"
      
      x <- "string"
      sprintf("Substitute in multiple strings: %s %s", x, "string2")
      # "Substitute in multiple strings: string string2"
      
      # To print a percent sign, use "%%"
      sprintf("A single percent sign here %%")
      # "A single percent sign here %"
      #寫入文件,重定向sink()
      #sink()重定向文件寫入
      
      # Start writing to an output file
      sink('analysis-output.txt')
      
      set.seed(12345)
      x <-rnorm(10,10,1)
      y <-rnorm(10,11,1)
      # Do some stuff here
      cat (sprintf("x has %d elements:\n", length(x)))
      print(x)
      cat ("y =", y, "\n")
      
      cat("=============================\n")
      cat("T-test between x and y\n")
      cat("=============================\n")
      t.test(x,y)
      
      # Stop writing to the file
      sink()
      
      
      # Append to the file
      sink('analysis-output.txt', append=TRUE)
      cat("Some more stuff here...\n")
      sink()
    
  • 字符串的定制輸出

      這個內容有點類似於字符串的連接。這里用到了strtrim(),用於將字符串修剪到特定的顯示寬度,其命令形式如下:strtrim(x, width)該函數返回的字符串向量的長度等於參數x的長度。

      strtrim(c("abcde", "abcde", "abcde"), c(1, 5, 10))
      ## [1] "a"     "abcde" "abcde"
      strtrim(c(1, 123, 12345), 4)  #短向量循環
      ## [1] "1"    "123"  "1234"
    

      strtrim()會根據width參數提供的數字來修剪字符串,若width提供的數字大於字符串的字符數的話,則該字符串會保持原樣,不會增加空格之類的東西。

      strwrap()會把字符串當成一個段落來處理(不管段落中是否有換行),按照段落的格式進行縮進和分行,返回結果就是一行行的字符串,其命令形式如下:strwrap(x, width, indent= 0, exdent= 0, prefix= “”, simplify= T, initial= prefix)函數返回結果中的每一行的字符串中的字符數目等於參數width。

      string <- "Each character string in the input is first split into\n paragraphs (or lines containing whitespace only). The paragraphs are then formatted by breaking lines at word boundaries."
      string
      ## [1] "Each character string in the input is first split into\n paragraphs (or lines containing whitespace only). The paragraphs are then formatted by breaking lines at word boundaries."
      cat(string)
      ## Each character string in the input is first split into
      ##  paragraphs (or lines containing whitespace only). The paragraphs are then formatted by breaking lines at word boundaries.
      strwrap(string)  #直接將換行符忽略了
      ## [1] "Each character string in the input is first split into paragraphs"
      ## [2] "(or lines containing whitespace only). The paragraphs are then"   
      ## [3] "formatted by breaking lines at word boundaries."
      strwrap(string, width = 40, indent = 4)  #首行縮進
      ## [1] "    Each character string in the input"
      ## [2] "is first split into paragraphs (or"    
      ## [3] "lines containing whitespace only). The"
      ## [4] "paragraphs are then formatted by"      
      ## [5] "breaking lines at word boundaries."
      strwrap(string, width = 40, exdent = 4)  #除了首行的其余行縮進
      ## [1] "Each character string in the input is" 
      ## [2] "    first split into paragraphs (or"   
      ## [3] "    lines containing whitespace only)."
      ## [4] "    The paragraphs are then formatted" 
      ## [5] "    by breaking lines at word"         
      ## [6] "    boundaries."
      strwrap(string, width = 40, simplify = F)  # 返回結果是個列表,而不再是個字符串向量
      ## [[1]]
      ## [1] "Each character string in the input is"
      ## [2] "first split into paragraphs (or lines"
      ## [3] "containing whitespace only). The"     
      ## [4] "paragraphs are then formatted by"     
      ## [5] "breaking lines at word boundaries."
      strwrap(string, width = 40, prefix = "******")
      ## [1] "******Each character string in the"    
      ## [2] "******input is first split into"       
      ## [3] "******paragraphs (or lines containing" 
      ## [4] "******whitespace only). The paragraphs"
      ## [5] "******are then formatted by breaking"  
      ## [6] "******lines at word boundaries."
    

參考資料


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM