-1

2 つの部分に解析する文字列変数があります。最初の列に元の文字列があり、他の列に抽出された各部分があるマトリックスを返すパッケージを使用str_matchして、これにアプローチすると考えました。stringr

これら 2 つの部分を抽出するための正規表現を約 10 個見つけました。(パーツははしごであり、支払いスケジュールのラングであり、非常に面倒です。一連のネストされたifelseステートメントを使用して関数を定義することにより、正規表現が機能することを確認しました。)

library(stringr)
library(data.table)
my_strs <- c("A 01","G 00","A    2")
mydt <- data.table(strs = my_strs)

rx1 <- '^([[:alpha:]] )([[:digit:]]{2})$'
rx2 <- '(A)    ([[:digit:]])'

正規表現を順番にチェックし、最初にチェックアウトしたものを使用してパーツを抽出したいと思います。正規表現が 1 つしかない場合は、次のようにすることができます。

myfun <- function(x){
    y <- str_match(x,rx1)
    return(y)
}
mydt[,myfun(strs)] 
#      [,1]   [,2] [,3]
# [1,] "A 01" "A " "01"
# [2,] "G 00" "G " "00"
# [3,] NA     NA   NA  

(それが機能するようになるまでにも長い時間がかかりました。関数の とVectorizeのすべての組み合わせを試し、呼び出しで ing を実行しました。)as.list*apply

正規表現を順番にチェックする私の最善の試みは、このかなり醜いクラッジです:

myfun2 <- function(x){
    y <- str_match(x,rx1)
    ifelse(!is.na(y[1]),"",(y <- str_match(x,rx2))[1])
    return(y)
}
mydt[1:2,myfun2(strs)] 
#      [,1]   [,2] [,3]
# [1,] "A 01" "A " "01"
# [2,] "G 00" "G " "00"
mydt[3,myfun2(strs)] 
#      [,1]     [,2] [,3]
# [1,] "A    2" "A"  "2" 
mydt[1:3,myfun2(strs)]
#      [,1]   [,2] [,3]
# [1,] "A 01" "A " "01"
# [2,] "G 00" "G " "00"
# [3,] NA     NA   NA  

ご覧のとおり、まだ完全には機能していません。

これにアプローチするためのより良い方法について何か考えはありますか? データ セットには約 350 万行ありますが、この文字列の一意の値は約 2000 しかないため、効率についてはあまり心配していません。

4

2 に答える 2

1

gsubfn パッケージを使用strapplyしてこれを試してください。一致を受け入れ、最初の 2 つの空でないものを返す関数を定義します。次に、の各コンポーネントの正規表現で使用します。paste(rx1, rx2, sep = "|")my_str

library(gsubfn)

# test data
# there was an addition to the question in the comments.  It asked to be able to handle
# one regular expression which has only a single capture.  Make sure its at the end.
rx3 <- "^([[:digit:]]{2})$"
my_strs2 <- c(my_strs, "99")    

# code
first2 <- function(...) { x <- c(..., NA); head(x[x != ""], 2) }
strapply(my_strs2, paste(rx1, rx2, rx3, sep = "|"), first2, simplify = TRUE)

最後の行は次を返します。

    [,1] [,2] [,3] [,4]
[1,] "A " "G " "A"  "99"
[2,] "01" "00" "2"  NA  

(my_strsまったく一致しない のコンポーネントがある場合、それらのコンポーネントが NULL であるリストが返されます。その場合、 を削除してsimplify = TRUE、常にリストを返すようにすることをお勧めします。)

注: strapplyc同じパッケージでは、R で書かれているのに対し、その中身は tcl (文字列処理言語) で書かれているため、はるかに高速です。strapplystrapply

L <- strapplyc(my_strs2, paste(rx1, rx2, rx3, sep = "|"))
sapply(L, first2)
于 2013-05-06T20:59:35.130 に答える
0

後世のために、今日見つけた別の解決策を次に示します。

mydt[,{
    i_rx <- min(which(unlist(sapply(rx_list,function(x)grepl(x,strs)))))
    as.list(str_match(strs,rx_list[[i_rx]]))
},by=1:nrow(mydt)]

正規表現にいくつかの小さな変更を加えて、それらをリストに入れました。

rx1  <- '^([[:alpha:]] )([[:digit:]]{2})$'
rx2a <- "^(A)    ([[:digit:]])$"
rx3a <- "^()([[:digit:]]{2})$"
rx_list <- list(rx1,rx2a,rx3a)
于 2013-05-14T03:46:40.183 に答える