2017-01-11 14 views
2

別の列内の文字列の一部に基づいて列を作成したいとします。データテーブル内で可変長の文字列を分割します

参照列は、一般的な形式は以下の:私はこの場合には単語「リン」を抽出するGB /リン12月31日

および様々な長さのものです。

私のアプローチは、これまでされています:

library(data.table) 
d1 <- data.table(MENU_HINT = 
       c("GB/Ling 31st Dec", "GB/Taun 30th Dec", 
        "GB/Ayr 19th Dec", "GB/Ayr 9th Nov", 
        "GB/ChelmC 29th Sep"), 
      Track = c("Ling", "Taun", "Ayr", "Ayr", "ChelmC")) 

#remove all the spaces 
d1[, Track2 := gsub("[[:space:]]", "", MENU_HINT)] 

# get the position of the first digit 
d1[, x := as.numeric(regexpr("[[:digit:]]", Track2)[[1]])] 

# get the position of the '/' 
d1[, y := as.numeric(regexpr("/", Track2))[[1]]] 

# use above to extract the Track 
d1[, Track2 := substr(Track2, y + 1, x - 1)] 

トラックは私が得ることを期待するものであるとトラック2は、私は上記の私のコードから得るものです。

これは長時間巻き込まれているようで、x値とy値が列全体で同じであるため動作していないようです。

+1

可能性があり、パッケージ 'stringr'の' str_extract'機能に小さな再現性の例と予想される出力 – akrun

+0

表情を見せてください。 – LAP

+0

@akrun謝罪、小さな例が追加されました。 – MidnightDataGeek

答えて

4

とで行うことができます。あなたが探している言葉は、常に第2の空間の後ろにあるようです。非常にシンプルかつ効率的なソリューションを

d1[, Track2 := tstrsplit(MENU_HINT, " ", fixed = TRUE)[[3]]] 

ベンチマーク

bigDT <- data.table(MENU_HINT = sample(d1$MENU_HINT, 1e6, replace = TRUE)) 
microbenchmark::microbenchmark("sub: " = sub("\\S+[[:punct:] ]+(\\S+).*", "\\1", bigDT$MENU_HINT), 
           "gsub: " = gsub("^[^/]+/\\s*|\\s+.*$", "", bigDT$MENU_HINT), 
           "tstrsplit: " = tstrsplit(bigDT$MENU_HINT, " ", fixed = TRUE)[[3]]) 
# Unit: milliseconds 
#  expr  min  lq  mean median  uq  max neval 
#  sub: 982.1185 998.6264 1058.1576 1025.8775 1083.1613 1405.051 100 
#  gsub: 1236.9453 1262.6014 1320.4436 1305.6711 1339.2879 1766.027 100 
# tstrsplit: 385.4785 452.6476 498.8681 470.8281 537.5499 1044.691 100 
2

私たちは、私はそれは大きなデータセットのために効率的ではありませんthis-のための正規表現を使用していないだろうsub

d1[, Track2 := sub("\\S+[[:punct:] ]+(\\S+).*", "\\1", MENU_HINT)] 

それともgsub

d1[, Track2 := gsub("^[^/]+/\\s*|\\s+.*$", "", MENU_HINT)] 
d1 
#    MENU_HINT Track Track2 
#1: GB/Ling 31st Dec Ling Ling 
#2: GB/Taun 30th Dec Taun Taun 
#3: GB/Ayr 19th Dec Ayr Ayr 
#4:  GB/Ayr 9th Nov Ayr Ayr 
#5: GB/ChelmC 29th Sep ChelmC ChelmC 
+0

クイック返信ありがとう。 「サブ」は私のデータの2より少し速いようです。 – MidnightDataGeek

関連する問題