2013-02-24 9 views
6

Einträge Ich habe einen Datenrahmen bekommt, die das folgende FormularSplit-Strings in Spalten in R, wobei jeder String eine möglicherweise unterschiedliche Anzahl von Spalten hat

pages       count 
[page 1, page 2, page 3]  23 
[page 2, page 4]    4 
[page 1, page 3, page 4]  12 

Und was bekommt ist muß ich tun ist, die erste Spalte geteilt an den Kommas und erstellen Sie genügend neue Spalten, um die längste Sequenz abzudecken. Das Ergebnis sollte sein:

First Page  Second Page Third Page  Count 
page 1   page 2  page 3   23 
page 2   page 4  null   4 
page 1   page 3  page 4   12 

ich in Ordnung bin, ob die Null eine Zeichenfolge der Länge Null ist, und ich kann behandeln die Klammern Abstreifen.

Antwort

3

Beispieldaten

myDat <- read.table(text= 
    "pages|count 
[page 1, page 2, page 3]|23 
[page 2, page 4]|4 
[page 1, page 3, page 4]|12", header=TRUE, sep="|") 

Wir pages aus myDat ziehen kann, daran zu arbeiten.

# if factors, convert to characters 
pages <- as.character(myDat$page) 

# remove brackets. Note the double-escape's in R 
pages <- gsub("(\\[|\\])", "", pages) 

# split on comma 
pages <- strsplit(pages, ",") 

# find the largest element 
maxLen <- max(sapply(pages, length)) 

# fill in any blanks. The t() is to transpose the return from sapply 
pages <- 
t(sapply(pages, function(x) 
     # append to x, NA's. Note that if (0 == (maxLen - length(x))), then no NA's are appended 
     c(x, rep(NA, maxLen - length(x))) 
)) 

# add column names as necessary 
colnames(pages) <- paste(c("First", "Second", "Third"), "Page") 

# Put it all back together 
data.frame(pages, Count=myDat$count) 



Ergebnisse

> data.frame(pages, Count=myDat$count) 
    First.Page Second.Page Third.Page Count 
1  page 1  page 2  page 3 23 
2  page 2  page 4  <NA>  4 
3  page 1  page 3  page 4 12 
+0

Ricardo sieht, dass wir eine Vorverarbeitung vor usinf diese Lösung benötigen, tun Sie * hinzufügen müssen | * als Trennzeichen? – agstudy

+0

@agstudy, keine Vorverarbeitung erforderlich. Ich habe die '|' in die Beispieldaten einfach hinzugefügt, um das Kopieren und Einfügen zu erleichtern, aber es verschwindet in der gleichen Zeile (zB durch 'read.table'). Da der OP dem Datenrahmen keinen Namen gab, nannte ich ihn "myDat". Es sollte alles kopierbar sein. –

+0

Das ist bang on. Vielen Dank! – TWAndrews

2

read.table mit fill=TRUE können sie in füllen. Die names(DF2)<- Zeile, wenn schöne Spaltennamen sind nicht wichtig weggelassen werden könnte. Keine Pakete werden verwendet.

# test data 

Lines <- "pages       count 
[page 1, page 2, page 3]  23 
[page 2, page 4]    4 
[page 1, page 3, page 4]  12" 

# code - replace text=Lines with something like "myfile.dat" 

DF <- read.table(text = Lines, skip = 1, sep = "]", as.is = TRUE) 
DF2 <- read.table(text = DF[[1]], sep = ",", fill = TRUE, as.is = TRUE) 
names(DF2) <- paste0(read.table(text = Lines, nrow = 1, as.is = TRUE)[[1]], seq_along(DF2)) 
DF2$count <- DF[[2]] 
DF2[[1]] <- sub(".", "", DF2[[1]]) # remove [ 

die gibt dies:

> DF2 
    pages1 pages2 pages3 count 
1 page 1 page 2 page 3 23 
2 page 2 page 4    4 
3 page 1 page 3 page 4 12 

Hinweis: Dies gibt Spaltenüberschriften der Seiten 1, 2, usw. Wenn es dann in der Frage genau die Spaltenüberschriften gezeigt zu haben, wichtig war zu ersetzen, Linie mit dieser, die diese Überschriften verwendet, wenn es weniger als 20 Seitenspalten gibt.

ord <- c('First', 'Second', 'Third', 'Fourth', 'Fifth', 'Sixth', 'Seventh', 
'Eighth', 'Ninth', 'Tenth', 'Eleventh', 'Twelfth', 'Thirteenth', 
'Fourteenth', 'Fiftheenth', 'Sixteenth', 'Seventeenth', 'Eighteenth', 
'Nineteenth') 
ix <- seq_along(DF2) 
names(DF2) <- if (ncol(DF2) < 20) paste(ord[ix], "Page") else paste("Page", ix) 
4

Mein "splitstapshape" -Paket hat eine Funktion, die diese Art von Problem anspricht. Die entsprechende Funktion ist in diesem Fall concat.split und funktioniert wie folgt („myDat“ von Ricardo Antwort verwenden):

# Get rid of "[" and "]" from your "pages" variable 
myDat$pages <- gsub("\\[|\\]", "", myDat$pages) 
# Specify the source data.frame, the variable that needs to be split up 
# and whether to drop the original variable or not 
library(splitstackshape) 
concat.split(myDat, "pages", ",", drop = TRUE) 
# count pages_1 pages_2 pages_3 
# 1 23 page 1 page 2 page 3 
# 2  4 page 2 page 4   
# 3 12 page 1 page 3 page 4 
Verwandte Themen