2016-05-03 6 views
1

Mein Datenrahmen hat Spalten, die ich durch Bindestriche teilen möchte, doppelte Zeilen mit Zeichen links und rechts von Bindestrichen. Ich weiß, wie man spaltet und dupliziert, kann aber nicht herausfinden, wie man Teile von Strings behält. Ziemlich schreckliche Beschreibung - Ich denke, es ist einfach, den Datenrahmen und die gewünschte Ausgabe zu zeigen.R: Teilen und Duplizieren einer Zeile

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 

Meine gewünschte Ausgabe sollte wie folgt aussehen:

        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 

Oder zumindest so, durch Strich geteilt mit "oz"

        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 

Jede Hilfe wird sehr geschätzt !!

+0

Sind alle Zeilen der Form:

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 = "")) } 

Diese Funktion kann auch Strings mit drei oder mehr Zahl Spezifikationen umgehen? – Stibu

+0

Kann auch "10 Pack 14 - 16 Unzen kann" –

Antwort

1

Werfen Sie einen Blick auf diese Funktion

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") 
} 

Es ist auf Strings angewendet werden, die in der Unit.Types Spalte sind. Beispiel:

> 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" 

Dann mit dieser Funktion wir folgendes tun:

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 ist unser Wunsch data.frame.

UPD Bezüglich Ihrer Anmerkung: Wir können Regex verwenden, die durch ' - ' getrennt Zahlenpaare übereinstimmt, oder einfach nur Zahlen und schreiben f mit ihm. „- 12er 11,2-14,9 oz Flasche oder Dose 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

Vielen Dank! Dies funktioniert hervorragend mit dem Ende der Zeichenfolge "oz Bottle or Can". In allgemeineren Fällen wird das Ende zweimal wiederholt (z.B. kann das Ende der Saite "Blah .. 10 - 12 oz Can" oder eine andere Form sein - Flasche, Fass, etc.). –

Verwandte Themen