Estoy tratando de leer un archivo de texto con diferentes longitudes de hilera:

1
1   2
1   2   3
1   2   3   4
1   2   3   4   5
1   2   3   4   5   6
1   2   3   4   5   6   7
1   2   3   4   5   6   7   8

Para superar este problema, estoy usando el argumento de relleno=TRUE en la lectura.tabla, así:

data<-read.table("test",sep="\t",fill=TRUE)

Por desgracia, para evaluar la máxima longitud de la fila, leer.la tabla se lee solo las 5 primeras líneas del archivo, y genera un objeto como este:

data
   V1 V2 V3 V4 V5
1   1 NA NA NA NA
2   1  2 NA NA NA
3   1  2  3 NA NA
4   1  2  3  4 NA
5   1  2  3  4  5
6   1  2  3  4  5
7   6 NA NA NA NA
8   1  2  3  4  5
9   6  7 NA NA NA
10  1  2  3  4  5
11  6  7  8 NA NA

Es allí una manera a fuerza de leer.tabla para desplazarse sobre el archivo completo para evaluar la máxima longitud de la fila?
Sé que una posible solución sería la de proporcionar el número de la columna, como:

data<-read.table("test",sep="\t",fill=TRUE,col.names=c(1:8))

Pero desde que tengo un montón de archivos, quería evaluar este automáticamente dentro de R. Alguna sugerencia? 🙂


EDIT: el archivo original no contiene números progresivos, por lo que esta no es una solución:

data1<-read.table("test",sep="\t",fill=TRUE)
data2<-read.table("test",sep="\t",fill=TRUE,col.names=c(1:max(data1))
  • Se puede poner un encabezado en el archivo (es decir, hacer que los archivos tienen un formato coherente)?
  • Por desgracia no, los archivos son generados externamente y cada fila puede tener un número aleatorio de las entradas.

2 Comentarios

  1. 55

    No es bonito función count.fields (ver ayuda) que cuenta el número de columnas por fila:

    count.fields("test", sep = "\t")
    #[1] 1 2 3 4 5 6 7 8

    Así, usando la segunda solución:

    no_col <- max(count.fields("test", sep = "\t"))
    data <- read.table("test",sep="\t",fill=TRUE,col.names=1:no_col)
    data
    #   X1 X2 X3 X4 X5 X6 X7 X8
    # 1  1 NA NA NA NA NA NA NA
    # 2  1  2 NA NA NA NA NA NA
    # 3  1  2  3 NA NA NA NA NA
    # 4  1  2  3  4 NA NA NA NA
    # 5  1  2  3  4  5 NA NA NA
    # 6  1  2  3  4  5  6 NA NA
    # 7  1  2  3  4  5  6  7 NA
    # 8  1  2  3  4  5  6  7  8
  2. 5

    Utilizando count.fields es definitivamente el mejor enfoque para esto, pero sólo para la integridad:

    Otra opción es traer todo el texto sin procesar y analizar dentro de R:

    x <- readLines(textConnection(
    "1\t
    1\t2
    1\t2\t3
    1\t2\t3\t4
    1\t2\t3\t4\t5
    1\t2\t3\t4\t5\t6"))
    x <- strsplit(x,"\t")

    Combinar una lista de desigualdad en la longitud de los vectores, el enfoque más sencillo es utilizar el rbind.fill función de plyr:

    library(plyr)
    # requires data.frames with column names
    x <- lapply(x,function(x) {x <- as.data.frame(t(x)); colnames(x)=1:length(x); return(x)})
    do.call(rbind.fill,x)
    1    2    3    4    5    6
    1 1 <NA> <NA> <NA> <NA> <NA>
    2 1    2 <NA> <NA> <NA> <NA>
    3 1    2    3 <NA> <NA> <NA>
    4 1    2    3    4 <NA> <NA>
    5 1    2    3    4    5 <NA>
    6 1    2    3    4    5    6

Dejar respuesta

Please enter your comment!
Please enter your name here