2017-06-14 10 views
3

大きなデータセット(〜1500行)で作業していますが、データセットを作成したときに、 1つの長い文字列にまとめられます。文字列を3つの列に区切ります:テキスト、数値、テキスト

識別文字列は、 "Polygon_Name"というラベルの列にあります。私はこの列を保持し、この列の文字列値を3つの列に分割したいと思います。

たとえば、「Polygon_Name」セルにCanker14Bなどの番号が埋め込まれている場合は、次の列が表示されます。(1)元のPolygon_Name、(2)前のすべてのテキスト番号、(3)番号、(4)番号の後のすべてのテキスト。私がしました

enter image description here

私のデータの小さなサブセット:

df <- structure(list(Bolt_ID = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L), .Label = "N1T.3.4.15.0.C", class = "factor"), 
    Polygon_Name = structure(c(10L, 1L, 9L, 6L, 3L, 7L, 2L, 8L, 
    4L, 5L), .Label = c("C", "Canker15B", "Canker15Left", "Canker15Right", 
    "Canker16", "Canker17", "CankS15B", "CankS16", "CankS17", 
    "S"), class = "factor"), Measure = c(19.342, 25.962, 0.408, 
    0.008, 0.074, 0.41, 0.011, 0.251, 0.056, 0.034)), .Names = c("Bolt_ID", 
"Polygon_Name", "Measure"), row.names = c(1L, 2L, 4L, 5L, 6L, 
7L, 8L, 9L, 10L, 11L), class = "data.frame") 

電流出力:

enter image description here

究極出力に(私はこれを手動で構築されました)抽出する方法を考え出した次のコード番号:

library(stringr) 
regexp <- "[[:digit:]]+" 
df$Poly_Num <- str_extract(df$Polygon_Name, regexp) 

しかし、私はまだ数字の前後にテキストを引き出すのに苦労しています。いかなる考えも認められるだろう。

答えて

3

tidyverse経由アイデアは次のようになり、

library(tidyverse) 

df %>% 
mutate(Poly_num = gsub('\\D+', '', Polygon_Name)) %>% 
separate(Polygon_Name, into = c('Poly_type', 'Poly_letter'), sep = '[0-9]+', remove = FALSE) 

#   Bolt_ID Polygon_Name Poly_type Poly_letter Measure Poly_num 
#1 N1T.3.4.15.0.C    S   S  <NA> 19.342   
#2 N1T.3.4.15.0.C    C   C  <NA> 25.962   
#3 N1T.3.4.15.0.C  CankS17  CankS    0.408  17 
#4 N1T.3.4.15.0.C  Canker17 Canker    0.008  17 
#5 N1T.3.4.15.0.C Canker15Left Canker  Left 0.074  15 
#6 N1T.3.4.15.0.C  CankS15B  CankS   B 0.410  15 
#7 N1T.3.4.15.0.C  Canker15B Canker   B 0.011  15 
#8 N1T.3.4.15.0.C  CankS16  CankS    0.251  16 
#9 N1T.3.4.15.0.C Canker15Right Canker  Right 0.056  15 
#10 N1T.3.4.15.0.C  Canker16 Canker    0.034  16 

ワンライナーは、あなたは、あなたがすでにstringr使用しているのでextracttidyrから(@docendodiscimusの賛辞)

tidyr::extract(df, Polygon_Name, c("a","b","c"), "^([^0-9]+)(\\d*)([^0-9]*)$", 
                 remove = FALSE, convert = TRUE) 
1

を使用することですこれらを得ることができますstr_match

str_match(df$Polygon_Name, "([[:alpha:]]*)([[:digit:]]*)([[:alpha:]]*)")[,2:4] 
     [,1]  [,2] [,3] 
[1,] "S"  "" ""  
[2,] "C"  "" ""  
[3,] "CankS" "17" ""  
[4,] "Canker" "17" ""  
[5,] "Canker" "15" "Left" 
[6,] "CankS" "15" "B"  
[7,] "Canker" "15" "B"  
[8,] "CankS" "16" ""  
[9,] "Canker" "15" "Right" 
[10,] "Canker" "16" "" 

これを既存のdata.frameに追加するには、

PName = str_match(df$Polygon_Name, "([[:alpha:]]*)([[:digit:]]*)([[:alpha:]]*)")[,2:4] 
df = data.frame(df, PName) 
names(df)[4:6] = c("Poly_Type", "Poly_Num", "Poly_Letter") 
+0

非常にきれいな短いオプションを使用できます。私はこの解決策がどの列にも「NA」を置かないことも好きです。 – KKL234

関連する問題