2013-07-22 9 views
14

Jaki jest najlepszy sposób odczytywania pliku na R, gdy nagłówek ma dwie niezbędne linie do nagłówka?Czytanie nagłówków dwuliniowych w R

Zdarza mi się to przez cały czas, ponieważ ludzie często używają jednej linii dla nazwy kolumny, a następnie dołączają do niej kolejną linię dla jednostki miary. Nie chcę niczego pomijać. Chcę, żeby nazwiska i jednostki do nich dotarły.

Oto co typical file with two headers might look like:

trt biomass yield 
crop Mg/ha bu/ac 
C2  17.76 205.92 
C2  17.96 207.86 
CC  17.72 197.22 
CC  18.42 205.20 
CCW  18.15 200.51 
CCW  17.45 190.59 
P  3.09 0.00 
P  3.34 0.00 
S2  5.13 49.68 
S2  5.36 49.72 
+0

Plik, z którym się łączysz ma nagłówek jednoliniowy ... Zaktualizuj i powiedz nam, jakie powinny być oczekiwane nazwy kolumn data.frame. – flodel

+5

Sposób radzenia sobie z tą sytuacją nie polega na ponownym zadawaniu pytania, ale na nagradzaniu starego pytania. – joran

+0

Zgadzam się z @joran. Jeśli twoje pytanie jest zasadniczo inne, wyjaśnij różnice. –

Odpowiedz

15

chciałbym zrobić dwa kroki, zakładając, że wiemy, że pierwszy wiersz zawiera etykiety, i nie zawsze są dwa nagłówki.

header <- scan("file.txt", nlines = 1, what = character()) 
data <- read.table("file.txt", skip = 2, header = FALSE) 

Następnie dodać wektor znaków header się jako składnik names:

names(data) <- header 

dla danych byłoby to

header <- scan("data.txt", nlines = 1, what = character()) 
data <- read.table("data.txt", skip = 2, header = FALSE) 
names(data) <- header 

head(data) 

>  head(data) 
    trt biomass yield 
1 C2 17.76 205.92 
2 C2 17.96 207.86 
3 CC 17.72 197.22 
4 CC 18.42 205.20 
5 CCW 18.15 200.51 
6 CCW 17.45 190.59 

Jeśli chcesz jednostek, jak na @ odpowiedź Dwin za , a następnie wykonaj drugą próbkę: scan() w linii 2

header2 <- scan("data.txt", skip = 1, nlines = 1, what = character()) 
names(data) <- paste0(header, header2) 

> head(data) 
    trtcrop biomassMg/ha yieldbu/ac 
1  C2  17.76  205.92 
2  C2  17.96  207.86 
3  CC  17.72  197.22 
4  CC  18.42  205.20 
5  CCW  18.15  200.51 
6  CCW  17.45  190.59 
+0

Najpierw otrzymałeś niewłaściwy link. OP to zredagował. –

+0

@DWin Tak, wiem, ale wydaje mi się, że w tej chwili otrzymuję wersję z pamięci podręcznej. –

+0

https://www.dropbox.com/s/9328klp413xej8g/data.txt –

9

Zastosowanie readLines z 2 do limitu, analizować je, paste0 je ze sobą, a następnie odczytywane z read.table z skip =2 i header=FALSE (domyślnie). Zakończyć proces off z cesją nazwy kolumn:

dat <- "trt biomass yield 
crop Mg/ha bu/ac 
C2 17.76 205.92 
C2 17.96 207.86 
CC 17.72 197.22 
CC 18.42 205.20 
CCW 18.15 200.51 
CCW 17.45 190.59 
P 3.09 0.00 
P 3.34 0.00 
S2 5.13 49.68 
S2 5.36 49.72 
" 

Pewnie można wykorzystać argument pliku, ale przy użyciu text argumentu do odczytu funkcji sprawia, że ​​to bardziej samodzielne:

readLines(textConnection(dat),n=2) 
#[1] "trt\tbiomass\tyield" "crop\tMg/ha\tbu/ac" 
head2 <- read.table(text=readLines(textConnection(dat),n=2), sep="\t", stringsAsFactors=FALSE) 
with(head2, paste0(head2[1,],head2[2,])) 
# [1] "trtcrop"  "biomassMg/ha" "yieldbu/ac" 
joinheadrs <- with(head2, paste0(head2[1,],head2[2,])) 

newdat <- read.table(text=dat, sep="\t",skip=2) 
colnames(newdat)<- joinheadrs 
#------------------- 
> newdat 
    trtcrop biomassMg/ha yieldbu/ac 
1  C2  17.76  205.92 
2  C2  17.96  207.86 
3  CC  17.72  197.22 
4  CC  18.42  205.20 
5  CCW  18.15  200.51 
6  CCW  17.45  190.59 
7  P   3.09  0.00 
8  P   3.34  0.00 
9  S2   5.13  49.68 
10  S2   5.36  49.72 

Might być lepiej użyć pasty z podkreślenia-Sep:

joinheadrs <- with(head2, paste(head2[1,],head2[2,] ,sep="_") ) 
joinheadrs 
#[1] "trt_crop"  "biomass_Mg/ha" "yield_bu/ac" 
+0

Przepraszam, @DWin, wkleiłem niewłaściwy plik na początku. – Nazer

6

Prawie taki sam sposób do innych odpowiedzi, po prostu skrócenie do 2 stwierdzeń:

dat <- "trt biomass yield 
crop Mg/ha bu/ac 
C2  17.76 205.92 
C2  17.96 207.86 
CC  17.72 197.22 
CC  18.42 205.20 
CCW  18.15 200.51 
CCW  17.45 190.59 
P  3.09 0.00 
P  3.34 0.00 
S2  5.13 49.68 
S2  5.36 49.72" 

header <- sapply(read.table(text=dat,nrow=2),paste,collapse="_") 
result <- setNames(read.table(text=dat,skip=2),header) 

Wynik:

> head(result,2) 
    trt_crop biomass_Mg/ha yield_bu/ac 
1  C2   17.76  205.92 
2  C2   17.96  207.86 
... 
+0

+1 (przepraszam za całkowicie pominiętą 'nrow = 2') –

0

Nieco inny wyjaśnił krok po kroku podejście:

  1. Czytaj tylko pierwsze dwa wiersze plików jako dane (bez nagłówków):

    headers <- read.table("data.txt", nrows=2, header=FALSE) 
    
  2. Tworzenie nazw nagłówków z dwóch (lub więcej) pierwszych rzędach, sappy umożliwia wykonywanie operacji na kolumnach (w tym przypadku pasty) - read more about sapply here:

    headers_names <- sapply(headers,paste,collapse="_") 
    
  3. Czytaj dane pliki (z pominięciem pierwszych 2 rzędach):

    data <- read.csv(file="data.txt", skip = 2, header=FALSE) 
    
  4. i przypisz nagłówki drugim etapie do t on dane:

    names(data) <- headers_names 
    

zaletą jest to, że masz jasną kontrolę parametrów read.table (takich jak sep dla przecinkami, a stringAsFactors - zarówno dla nagłówków i dane)