R の文字列処理関数
R の文字列処理関数に付いて解説(ほとんどオンラインヘルプそのもの)します。これらは、文字列データの処理、データラベル、
出力・グラフィックス用の文字列、等に使われます。
> substr("abcdef",2,4) # "abcdef" の2番目から4番目の部分 [1] "bcd" > substring("abcdef",1:6,1:6) # 文字列を構成文字に分解(strsplit がより効率的) [1] "a" "b" "c" "d" "e" "f" > substr(rep("abcdef",4),1:4, 4:5) # "abcdef" の 1-4, 2-5, 3-4, 4-5 文字目を取り出す [1] "abcd" "bcde" "cd" "de" > x <- c("asfef", "qwerty", "yuiop[", "b", "stuff.blah.yech") # 文字列ベクトル > substr(x, 2, 5) # 各々の文字列の 2-5 文字目を取り出す [1] "sfef" "wert" "uiop" "" "tuff" > substring(x, 2, 4:6) # 各々の文字列の 2-4, 2-5, 2-6 文字目を取り出す [1] "sfe" "wert" "uiop[" "" "tuff" > substring(x, 2) <- c("..", "+++") # 各文字列の2文字目以降を "..", "+++" で(交互に)置き換え。 > x # "b" は短すぎるので何も置き換わらない [1] "a..ef" "q+++ty" "y..op[" "b" [5] "s..ff.blah.yech"
# 個々の文字への分解 (noquote は引用記号無しに出力する関数) > noquote(strsplit("A text I want to display with spaces", NULL)[[1]]) [1] A t e x t I w a n t t o d i s p l a y w i t h s p a c e s > x <- c(as = "asfef", qu = "qwerty", "yuiop[", "b", "stuff.blah.yech") # 文字列ベクトル > strsplit(x,"e") " 文字 "e" で分解 (文字 "e" は消える) $as [1] "asf" "f" $qu [1] "qw" "rty" [[3]] [1] "yuiop[" [[4]] [1] "b" [[5]] [1] "stuff.blah.y" "ch" > unlist(strsplit("a.b.c", ".")) # 正規表現 "." は任意の単一文字にマッチ [1] "" "" "" "" "" > unlist(strsplit("a.b.c", "\\.")) # 文字ピリオッド "." で分割 [1] "a" "b" "c" # 文字列の逆転関数 rev() を併用した例 # 文字列ベクトル x の各要素を個々の文字に分解したリストに変換し、各々逆転 # 次にそれらを paste 関数でつなぐ(sapply の引数はリスト、返り値はベクトル) > strReverse <- function(x) sapply(lapply(strsplit(x,NULL), rev), paste, collapse="") > strReverse(c("abc", "Statistics")) [1] "cba" "scitsitatS" # R-core メンバーの first name を得る > a <- readLines(file.path(R.home(),"AUTHORS"))[-(1:8)] # 最初の8要素(前置き)を除く > a [1] "Douglas Bates\t\t<bates@stat.wisc.edu>" [2] "John Chambers\t\t<jmc@research.bell-labs.com>" [3] "Peter Dalgaard\t\t<p.dalgaard@biostat.ku.dk>" [4] "Robert Gentleman\t<rgentlem@jimmy.dfci.harvard.edu>" [5] "Kurt Hornik\t\t<Kurt.Hornik@ci.tuwien.ac.at>" [6] "Stefano Iacus\t\t<stefano.iacus@unimi.it>" [7] "Ross Ihaka\t\t<ihaka@stat.auckland.ac.nz>" [8] "Friedrich Leisch\t<Friedrich.Leisch@univie.ac.at>" [9] "Thomas Lumley\t\t<tlumley@u.washington.edu>" [10] "Martin Maechler\t\t<maechler@stat.math.ethz.ch>" [11] "Duncan Murdoch\t\t<murdoch@stats.uwo.ca>" [12] "Paul Murrell\t\t<paul@stat.auckland.ac.nz>" [13] "Martyn Plummer\t\t<plummer@iarc.fr>" [14] "Brian Ripley\t\t<ripley@stats.ox.ac.uk>" [15] "Duncan Temple Lang\t<duncan@research.bell-labs.com>" [16] "Luke Tierney\t\t<luke@stat.umn.edu>" [17] "" [18] "plus Heiner Schwarte <h.schwarte@bluewin.ch> up to October 1999" [19] "and Guido Masarotto <guido@hal.stat.unipd.it> up to June 2003." > a <- a[(0:2)-length(a)] # 現メンバーだけ取り出す # 正規表現 " .*" は「空白の後に任意一文字の任意繰返し」の意味で、結局「(最初の)空白以降すべて」を意味する > (a <- sub(" .*","", a)) # 最初の空白以降を取り去る(空文字で置き換える) [1] "Douglas" "John" "Peter" "Robert" "Kurt" "Stefano" [7] "Ross" "Friedrich" "Thomas" "Martin" "Duncan" "Paul" [13] "Martyn" "Brian" "Duncan" "Luke"
> paste(1:12) # as.character(1:12) と同じ [1] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" > paste("A", 1:6, sep = "") # "A" がリサイクル使用される [1] "A1" "A2" "A3" "A4" "A5" "A6" > paste("A", 1:6) # sep="" を指定しないと空白が挿入される [1] "A 1" "A 2" "A 3" "A 4" "A 5" "A 6" # collapse の使用例。結果は単一の文字列になる > paste("A", 1:6, sep="",collapse="|") [1] "A1|A2|A3|A4|A5|A6" > paste("A", 1:6, sep="",collapse=" ") [1] "A1 A2 A3 A4 A5 A6" > paste("Today is", date()) # date() 関数の出力文字列と連結 [1] "Today is Sat Mar 20 17:22:23 2004" # 数値は文字列に変換後連結される(グラフィックスラベル等に重宝) > x <- pi > paste("pi =", x) [1] "pi = 3.14159265358979" > k=10; x=1:k; y=runif(k) > plot(x,y,xlab=paste("x values are 1:", k, sep=""), ylab=paste("y values are runif(", k, ")", sep=""))
nchar は文字ベクトル x を引数に取り、 その要素中の文字数からなるベクトルを返す
> x <- c("asfef","qwerty","yuiop[","b","stuff.blah.yech") > nchar(x) [1] 5 6 6 1 15 > mean # 平均値関数 mean の定義(内部関数) function (x, ...) UseMethod("mean") <environment: namespace:base> > deparse(mean) [1] "function (x, ...) " "UseMethod(\"mean\")" > nchar(deparse(mean)) [1] 18 17 > nchar("") [1] 0 > nchar(NULL) numeric(0) > nchar(NA) [1] 2
charmatch は、その第一引数の要素にマッチするものを、第二引数の中から探す
> charmatch("", "") [1] 1 # 空文字列の正確なマッチ > charmatch("m", c("mean", "median", "mode")) [1] 0 # 複数のマッチ > charmatch("me", c("mean", "median", "mode")) [1] 0 # 複数のマッチ > charmatch("med", c("mean", "median", "mode")) [1] 2 # ターゲットの2番目と正確なマッチ > charmatch(c("med","mo"), c("mean", "median", "mode")) [1] 2 3 # ターゲットの2,3番目と正確なマッチ
splus2R パッケージの、upperCase, lowerCase 関数
今更そんなもの。もともと base には toupper, tolower があります。実行速度もほぼ同じ。
toupper は、引数の文字列ベクトルの英小文字を英大文字に変換する。
tolower は、引数の文字列ベクトルの英大文字を英小文字に変換する。
> x <- "MiXeD cAsE 123" > tolower(x) [1] "mixed case 123" > toupper(x) [1] "MIXED CASE 123"
chartr は、第3引数の文字列ベクトル中の第1引数の文字を第2引数の文字に変換する。
> x <- "MiXeD cAsE 123" > chartr("a-z", "A-Z", x) # toupper と同じ結果になる [1] "MIXED CASE 123" > chartr("A-Z", "a-z", x) # tolower と同じ結果になる [1] "mixed case 123" > chartr("A-Z1-3", "a-z4-6", x) # 数字も置き換えることができる [1] "mixed case 456" > x <- "MiXeD cAsE 123@#" > chartr("A-Z1-3@#", "a-z4-6%$", x) # 当然,記号も置き換えることができる [1] "mixed case 456%$" > chartr(" !-~", "!-~ ", "This is a pen.") # 単純な暗号 [1] "Uijt!jt!b!qfo/" > chartr("あ-ん", "ア-ン", "あいうえお") # Windows でもできるかな? [1] "アイウエオ"
Windows 上で、日本語を含む文字列を処理した際に、そのままではwrite.dbf を実行すると、UTF-8 で出力されてしまう。このため iconv 関数を利用して以下のようにする必要がある。
library(foreign) dbf <- read.dbf("test.dbf") jchars <- gsub(" ","",chartr("$役所"," ",as.character(as.vector(dbf$textfield)))) dbf$textfield <- iconv(jchars,'UTF-8','SHIFT_JIS') write.dbf(dbf,"testnew.dbf")