2013-07-22 9 views
14

Qual è il modo migliore di leggere un file in R quando l'intestazione ha due righe necessarie per l'intestazione?Lettura di intestazioni a due righe in R

Questo mi succede sempre, poiché le persone spesso usano una riga per il nome della colonna e quindi includono un'altra linea al di sotto di essa per l'unità di misura. Non voglio saltare nulla. Voglio i nomi e le unità da portare avanti.

Ecco ciò che un 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

il file a cui è collegato ha un'intestazione di una riga ... Si prega di aggiornare e dirci quali dovrebbero essere i nomi delle colonne data.frame previsti. – flodel

+5

Il modo di gestire questa situazione non è di ri-chiedere la domanda, ma di mettere una taglia sulla vecchia domanda. – joran

+0

Sono d'accordo con @joran. Se la tua domanda è sostanzialmente diversa, ti preghiamo di spiegare le differenze. –

risposta

15

vorrei fare due passi, assumendo sappiamo che la prima riga contiene le etichette, e ci sono sempre due intestazioni.

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

Quindi aggiungere il vettore di carattere header come componente names:

names(data) <- header 

per i dati che questo sarebbe

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 

Se si desidera che le unità, come da @ risposta di DWin , quindi fare un secondo scan() sulla linea 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

All'inizio hai ricevuto il link sbagliato. L'OP lo ha modificato. –

+0

@DWin Sì, lo so, ma mi sembra di continuare a ottenere la versione memorizzata nella cache al momento. –

+0

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

9

Usa readLines con 2 per il limite, analizzarlo, paste0 insieme, quindi leggere con read.table con skip =2 e header=FALSE (impostazione predefinita). Completare il processo di via con l'assegnazione dei nomi di colonna:

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 
" 

Si sarebbe probabilmente utilizzare un file come argomento, ma utilizzando l'argomento text alle funzioni di lettura che rende questo più autosufficiente:

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 

Potenza meglio usare pasta con un carattere di sottolineatura-Set:

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

Mi dispiace, @DWin, ho incollato il file sbagliato all'inizio. – Nazer

6

Quasi lo stesso metodo per le altre risposte, semplicemente accorciando a 2 dichiarazioni:

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) 

risultati:

> 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 (scusate totalmente il 'nrow = 2') –

0

Un leggermente diverso spiegato passo passo approccio:

  1. Leggere solo le prime due righe dei file come dati (senza intestazioni):

    headers <- read.table("data.txt", nrows=2, header=FALSE) 
    
  2. Creare i nomi di intestazioni con i due (o più) prima fila, sappy consente di effettuare le operazioni sopra le colonne (in questo caso incolla) - read more about sapply here:

    headers_names <- sapply(headers,paste,collapse="_") 
    
  3. Leggi i dati dei file (saltando le prime 2 file):

    data <- read.csv(file="data.txt", skip = 2, header=FALSE) 
    
  4. e assegnare le intestazioni di fase due a t egli dati:

    names(data) <- headers_names 
    

Il vantaggio è che si dovrebbe avere chiaro il controllo dei parametri di read.table (come sep per le virgole, e stringAsFactors - sia per le intestazioni e i dati)

Problemi correlati