2016-05-03 10 views
1

私のデータフレームには、ダッシュで分割する列があり、ダッシュの左右に文字を含む行が重複しています。私は分割して複製する方法を知っていますが、文字列の一部を保持する方法を理解することはできません。かなりひどい記述 - データフレームと出力を表示するほうが簡単だと思います。R:行を分割して複製する

        Unit.Types Row.Count Test 
1 10 Pack 11.2 oz Bottle or Can  899 B 
2 10 Pack 14.9 oz Bottle or Can  899 B 
3 12 Pack 11.2 oz Bottle or Can  899 B 
4 12 Pack 14.9 oz Bottle or Can  899 B 
5 8 Pack 11.5 oz Bottle or Can  305 A 
6 8 Pack 16 oz Bottle or Can  305 A 
7 12 Pack 11.5 oz Bottle or Can  305 A 
8 12 Pack 16 oz Bottle or Can  305 A 

するか、少なくともそのように、 "オンス" とダッシュで分割さ

        Unit.Types Row.Count Test 
1 10 - 12 Pack 11.2 oz Bottle or Can  899 B 
2 10 - 12 Pack 14.9 oz Bottle or Can  899 B 
3 8 - 12 Pack 11.5 oz Bottle or Can  305 A 
4 8 - 12 Pack 16 oz Bottle or Can  305 A 

すべてのヘルプは大歓迎です!!:

tmp = structure(list(Unit.Types = c("10 - 12 Pack 11.2 - 14.9 oz Bottle or Can", 
"8 - 12 Pack 11.5 - 16 oz Bottle or Can"), Row.Count = c("899", 
"305"), Test = c("B", "A")), .Names = c("Unit.Types", "Row.Count", 
"Test"), row.names = c(104L, 196L), class = "data.frame") 

library(tidyr) 
library(dplyr) 

tmp2 = tmp %>% mutate(Unit.Types = strsplit(as.character(Unit.Types), "-")) %>% unnest(Unit.Types) 
tmp2 

    Row.Count Test    Unit.Types 
1  899 B     10 
2  899 B   12 Pack 11.2 
3  899 B 14.9 oz Bottle or Can 
4  305 A      8 
5  305 A   12 Pack 11.5 
6  305 A 16 oz Bottle or Can 

私の所望の出力は次のようになります。

+0

フォームのすべての行は、次のとおりです。

regex <- "[0-9]+(.[0-9]+)?(- [0-9]+(.[0-9]+)?)?" f <- function(x){ m <- gregexpr(regex, x) matches <- regmatches(x, m)[[1]] nonmatches <- regmatches(x, m, invert = T)[[1]][-1] strsplit(matches, " - ") %>% expand.grid(stringsAsFactors = F) %>% apply(MARGIN = 1, function(y) rbind(y, nonmatches) %>% c %>% paste(collapse = "")) } 

この関数は、3つ以上の数の仕様でも、文字列を扱うことができますか? – Stibu

+0

"10パック14 - 16オンスCan"にすることもできます –

答えて

1

はそれがUnit.Types列にある文字列に適用されるこの機能で

f <- function(x){ 
    strsplit(x, " Pack | oz Bottle or Can")[[1]] %>% 
    strsplit(" - ") %>% 
    expand.grid() %>% 
    mutate(V = paste(Var1, "Pack", Var2, "oz Bottle or Can")) %>% 
    `[[`("V") 
} 

を見てみましょう。例:

> f(tmp$Unit.Types[[1]]) 
[1] "10 Pack 11.2 oz Bottle or Can" "12 Pack 11.2 oz Bottle or Can" 
[3] "10 Pack 14.9 oz Bottle or Can" "12 Pack 14.9 oz Bottle or Can" 

はその後、この機能で、我々は次の操作を行うことができます。

ans <- tmp %>% split(1:nrow(tmp)) %>% 
lapply(function(x) data.frame(Unit.Types = f(x$Unit.Types), 
           Row.Count = x$Row.Count, 
           Test = x$Test 
          ) 
     ) %>% 
do.call(rbind, .) 
row.names(ans) <- NULL 

ansは、私たちの希望data.frameです。あなたのコメントについては

UPD:私たちは' - 'で区切られた数字のペアに一致する正規表現、または数字だけを使用して、それをfを書き換えることができます。 「 - 12パック11.2〜14.9オンスボトルや缶10」

> x <- "2 - 3 big packs of 10 - 12 Pack 11.2 - 14.9 oz Can" 
> f(x) 
[1] "2 big packs of 10 Pack 11.2 oz Can" "3 big packs of 10 Pack 11.2 oz Can" 
[3] "2 big packs of 12 Pack 11.2 oz Can" "3 big packs of 12 Pack 11.2 oz Can" 
[5] "2 big packs of 10 Pack 14.9 oz Can" "3 big packs of 10 Pack 14.9 oz Can" 
[7] "2 big packs of 12 Pack 14.9 oz Can" "3 big packs of 12 Pack 14.9 oz Can" 
+0

ありがとう!これは "oz Bottle or Can"という文字列の最後でうまくいきます。より一般的な場合、終了は2回繰り返されます(例えば、ストリングの終わりは "10〜12オンス・キャン"または他のフォーム - ボトル、樽など)。 –

関連する問題