2011-12-09 6 views
7

var ve her satır ayrı alanı belirtir zaman Ar içine bir metin dosyası okuyoruz nasıl. komplikasyon bazı kayıtlar 4 satır ve bazı alanların sayısındaki farklılık 1 ama iki yaşındayken hepsi ayrı düştü ne zaman 6. @DWin sorularımı çivilenmiş olması. Bir look at his answer here olabilir.her kayıt bir paragraf ve bazı kayıtlar 4 alanlara sahip ve diğerleri tek her kayıt bir paragraf olduğu bir metin dosyasında okuyabilirsiniz nasıl 6

Yani burada başlangıç ​​metni İşte

TheInstitute 5467 
    telephone line 4125526987 x 4567 
    datetime 2011110516 12:56 
    blay blay blah who knows what, but anyway it may have a comma 

TheInstitute 5467 
    telephone line 4125526987 x 4567 
    datetime 2011110516 12:58 
    blay blay blah who knows what 

TheInstitute 5467 
    telephone line 412552999 x 4999 
    bump phone line 4125527777 
    bump pony pony oops 4125527777 
    datetime 2011110516 12:59 
    blay blay blah who knows what 

TheInstitute 5467 
    telephone line 4125526987 x 4567 
    bump phone line 4125527777 
    bump pony pony oops 4125527777 
    datetime 2011110516 13:51 
    blay blay blah who knows what, but anyway it may have a comma 

TheInstitute 5467 
    telephone line 4125526987 x 4567 
    datetime 2011110516 14:56 
    blay blay blah who knows what 

çıkışı gibi görünmelidir ne benim son simülasyonudur. Aslında bu ihtiyacım olan şeylerden bir adım kaldırıldı. Aşağıda bir R data.frame'in ASCII metin gösterimini yerleştiriyorum. Her şeyin bir veri çerçevesinde olduğunu göreceksiniz, ancak bazı kayıtların iki ekstra alanı olduğundan, alan değerleri iki sütunla kaydırılır.

structure(list(institution = structure(c(1L, 1L, 1L, 1L, 1L), .Label = "TheInstitute 5467", class = "factor"), 
    telephoneline = structure(c(1L, 1L, 2L, 1L, 1L), .Label = c("telephone line 4125526987 x 4567", 
    "telephone line 412552999 x 4999"), class = "factor"), date.or.bump = structure(c(2L, 
    3L, 1L, 1L, 4L), .Label = c("bump phone line 4125527777", 
    "datetime 2011110516 12:56", "datetime 2011110516 12:58", 
    "datetime 2011110516 14:56"), class = "factor"), field4 = structure(c(2L, 
    1L, 3L, 3L, 1L), .Label = c("blay blay blah who knows what", 
    "blay blay blah who knows what, but anyway it may have a comma", 
    "bump pony pony oops 4125527777"), class = "factor"), field5 = structure(c(1L, 
    1L, 2L, 3L, 1L), .Label = c("", "datetime 2011110516 12:59", 
    "datetime 2011110516 13:51"), class = "factor"), field6 = structure(c(1L, 
    1L, 2L, 3L, 1L), .Label = c("", "blay blay blah who knows what", 
    "blay blay blah who knows what, but anyway it may have a comma" 
    ), class = "factor")), .Names = c("institution", "telephoneline", 
"date.or.bump", "field4", "field5", "field6"), class = "data.frame", row.names = c(NA, 
-5L)) 

PS: Ben inanmak haklı mıyım bu bir mesaj dput kullanarak veya bir bir .Rdata direclty burada dosyasını kaydedebilir bir veri çerçevesi.

cevap

9

muhtemelen daha zarif bir yolu yoktur, ancak bu işi olmalıdır.

x <- readLines("foo.txt") # read data with readLines 
nx <- !nchar(x)   # locate lines with only empty strings 
# create a list (split by empty lines, with empty lines removed) 
y <- split(x[!nx], cumsum(nx)[!nx]) 
# determine largest number of columns 
maxLength <- max(sapply(y,length)) 
# pad each list element with empty strings 
z <- lapply(y, function(x) c(x,rep("",maxLength-length(x)))) 
# create final matrix 
out <- do.call(rbind, z) 

Güncelleme: İşte

başka bir çözüm plyr::rbind.fill kullanıyor:

x <- readLines("foo.txt") # read data with readLines 
nx <- !nchar(x)   # locate lines with only empty strings 
# create final data.frame 
out <- rbind.fill(lapply(split(x[!nx], cumsum(nx)[!nx]), 
        function(x) data.frame(t(x)))) 
5

Diğer bir strateji seçtiğiniz bir dize kullanmaktır - EOL diyoruz - her satırın sonunu işaretlemek için ve daha sonra tüm satırları birlikte yapıştırın.

Daha sonra ilk mola dışarı kayıtlara strsplit iki tur kullanabilir ve sonra kayıtları içinde alanlarını patlak. (Alanlar tek bir EOL ile ayrılacaktır ise Kayıt, birbirini takip eden iki EOL s ayrılmış olur).

EOL <- "[email protected]" # (for instance) 
x <- readLines("filename.R") 
x <- paste(x, collapse=EOL)[[1]] 

x <- strsplit(x, paste(EOL, EOL, sep=""))   # Split apart records 
lapply(x, FUN=function(X) strsplit(X, EOL))[[1]] # Split apart fields w/in records 

bana bu yöntem temyiz ben (yani sep karakter olarak "\n\n" kullanın) ilk etapta dosyada okudum ama mümkün değildi olduğumda bunu yapmak Ben gibi ediyorum ne yakın olduğu için scan veya readLines biriyle yapmak.

2

Oku veriler dat < -. Readlines ("filename.txt") (Josh O'Brien çözümü esinlenerek) kayıtlarına göre

Bölünmüş veri

dat_rec <- lapply(strsplit(paste(dat,collapse="\n"),split="\n\n")[[1]], 
        function(x) strsplit(x,split="\n")[[1]]) 

(adlandırılmış vektörlere verileri Transform son alanı varsayalım yorumdur ve veri

dat_rec_vn <- lapply(dat_rec,function(x) { 
          vn <- gsub(" ","_",sub(" ","", 
             gsub("^(\\D*) \\d.*$","\\1", x[-length(x)]))) 
          y <- gsub("^(\\D*) (\\d.*)$","\\2",x[-length(x)]) 
          names(y) <- vn 
          return(y)}) 

verilerdeki alanın benzersiz adlar al) sayısal değeri ile başlar.

vn <- unique(unlist(lapply(dat_rec_vn,names),use.names=FALSE)) 

Alanı matrisle birleştirin ve adlarını verin.

dat_mat <- do.call(rbind,lapply(dat_rec_vn,function(x) { 
        y <- vector(mode="character",length=length(vn)) 
        y[match(names(x),vn)] <- x 
        return(y)})) 

colnames(dat_mat) <- vn 

İKİNCİ çözeltisi (kullanarak gawk)

gawk_cmd <- "gawk 'BEGIN{FS=\"\\n\";RS=\"\";OFS=\"\\t\";ORS=\"\\n\"} 
         {$1=$1; print $0}' test_multi.txt" 
dat <- strsplit(system(gawk_cmd,intern=TRUE),split="\t") 
NF <- do.call(max,lapply(dat,length)) 
M <- do.call(rbind,lapply(dat,"[",seq(NF))) 
+0

Eğer '[[1]]' ilk satırda ne yaptığını açıklayabilir misiniz? – Farrel

+0

strsplit, karakter vektörünün her elemanı için vektörlerin listesini döndürür (bir uzunluğun karakter vektörü için bile). Bu listede ilk elemana ihtiyacımız var, bu yüzden [[1]] bunu almak için kullanılıyor. Aynı işlev ikinci satırda kullanılır. –

+0

Oh, bu sadece ilk elementi istediği sürece bir listeyi vektör etmenin bir yolu olabilir mi? – Farrel

İlgili konular