2017-01-25 18 views
1

私はSOから利益をしてきた、かなり長い間、今、今サインアップにしようとすることを決めた)他人を助けると、b)偉大な男からの助けを得る:)(数が不足して?)文字列から3つの数字を抽出

cho <- c("[M-H]: C4H4O2", 
"[M+Hac-H]: C5H10O6", 
"[M-H]: C6H4O3", 
"[M+Fa-H]: C7H6O", 
"[M-H]: C9H8O3", 
"[M-H]: C18H30O3); 

私は数字を抽出するこのベクターからの順番に:私はこの(データのほんの少しのサブセット)のように見えたデータフレームから抽出されたベクトルを持って、私の質問に来るので

"C" の数を取得するには、 "H"、および "O" 原子:

temp <- strsplit(cho, "[^[:digit:]]"); 
temp <- as.numeric(unlist(temp)); 

#remove NAs 
temp <- temp[!is.na(temp)]; 

#split into three column matrix and convert to df to merge with original df 
temp <- as.data.frame(matrix(temp, ncol = 3, byrow = T)); 
Rが行列を生成するためのデータをリサイクルされる。この場合

は、大きなデータセットに対する私の場合には、生成されたtempベクトルは十分な長さと行列が生成なっているが、それは混乱です。これは、数字が2つしか抽出されない"[M+Fa-H]: C7H6O"などの場合によるものです。 "O"の後に "1"をつけて、3つの数字を2つではなく抽出できるようにするにはどうすればいいですか?このための回避策はありますか?

ご協力いただきありがとうございます!

答えて

2

str_extract_allを使用できます。 CまたはHまたはOは、listでこれらの数字を抽出し、変換のいずれか、次の1つ以上の数字(\\d+)と一致する正規表現の前後参照を使用するようにinteger

library(stringr) 
lst <- lapply(str_extract_all(cho, "(?<=C|H|O)\\d+"), as.integer) 

それともbase Rオプションが

です
read.csv(text=sub(".*C?(\\d+)H?(\\d+)O?(\\d*).*", 
       "\\1,\\2,\\3", cho), header=FALSE, fill=TRUE) 
+1

素晴らしいです!値が見つからない場合でも、私たちは1を挿入する必要があります –

+0

また、正規表現を説明することができますステップバイステップ –

+1

私よりもはるかに短いコードは、ありがとう! 'base R'の解決策は私には完璧です.NAsだけが置き換えられます! – munirbe