Mientras que los datos de las columnas del marco debe tener el mismo número de filas, ¿hay alguna manera de crear un marco de datos de diferente longitud. Yo no estoy interesado en el ahorro como separar los elementos de una lista, porque a menudo tengo que a las personas de email esta información como un archivo csv, y esto es más fácil como un marco de datos.

x = c(rep("one",2))
y = c(rep("two",10))
z = c(rep("three",5))
cbind(x,y,z)

En el código anterior, el cbind() función sólo recicla las columnas más cortas, de manera que todos ellos tienen 10 elementos en cada columna. ¿Cómo puedo modificar sólo lo que las longitudes de 2, 10, y 5.

He hecho esto en el pasado haciendo lo siguiente, pero es ineficiente.

  df = data.frame(one=c(rep("one",2),rep("",8)), 
           two=c(rep("two",10)), three=c(rep("three",5), rep("",5))) 
  • Este problema ha surgido before. El último es, probablemente, no es un duplicado, pero el primero es bastante cerca.
  • sí. en particular, mi respuesta es casi idéntica a la de dos respuestas que se dieron en la antigua. @Owen «subversivo» la respuesta es la novela, y listo (si es peligroso).
  • Esta pregunta es como preguntar ¿cómo puedo almacenar un entero que representa 2/3.
  • Usted podría también utilizar dput para almacenar datos en ascii (R-only) formato.
InformationsquelleAutor ATMathew | 2011-08-25

5 Comentarios

  1. 26

    Lo siento, este no es exactamente lo que usted pidió, pero creo que no puede ser de otra manera para conseguir lo que quieres.

    Primero, si los vectores son de diferente longitud, los datos no es realmente tabular, es? Cómo se trata sólo de salvar a los diferentes archivos CSV? También puede intentar ascii formatos que permiten almacenar varios objetos (json, XML).

    Si usted siente que los datos tabulares, usted podría pad en el NAs:

    > x = 1:5
    > y = 1:12
    > max.len = max(length(x), length(y))
    > x = c(x, rep(NA, max.len - length(x)))
    > y = c(y, rep(NA, max.len - length(y)))
    > x
     [1]  1  2  3  4  5 NA NA NA NA NA NA NA
    > y
     [1]  1  2  3  4  5  6  7  8  9 10 11 12

    Si usted absolutamente debe hacer un data.frame con la desigualdad de columnas que podría subvertir el cheque, a su propio riesgo:

    > x = 1:5
    > y = 1:12
    > df = list(x=x, y=y)
    > attributes(df) = list(names = names(df),
        row.names=1:max(length(x), length(y)), class='data.frame')
    > df
          x  y
    1     1  1
    2     2  2
    3     3  3
    4     4  4
    5     5  5
    6  <NA>  6
    7  <NA>  7
     [ reached getOption("max.print") -- omitted 5 rows ]]
    Warning message:
    In format.data.frame(x, digits = digits, na.encode = FALSE) :
      corrupt data frame: columns will be truncated or padded with NAs
    • attributes(df) = list( names = names(df), row.names=1:max.len, class = 'data.frame')
    • El ‘subvertir la» verificación de la opción no funciona con r.3.3.3 a través de RStudio 1.0.136. Se bloquea R.
  2. 6

    Otro enfoque para el relleno:

    na.pad <- function(x,len){
        x[1:len]
    }
    
    makePaddedDataFrame <- function(l,...){
        maxlen <- max(sapply(l,length))
        data.frame(lapply(l,na.pad,len=maxlen),...)
    }
    
    x = c(rep("one",2))
    y = c(rep("two",10))
    z = c(rep("three",5))
    
    makePaddedDataFrame(list(x=x,y=y,z=z))

    La na.pad() función explota el hecho de que R automáticamente la almohadilla de un vector con NAs si intenta índice de los elementos inexistentes.

    makePaddedDataFrame() sólo busca el más largo y rellena el resto hasta una longitud igual..

  3. 5

    Para amplificar @goodside la respuesta, puedes hacer algo como

    L <- list(x,y,z)
    cfun <- function(L) {
      pad.na <- function(x,len) {
       c(x,rep(NA,len-length(x)))
      }
      maxlen <- max(sapply(L,length))
      do.call(data.frame,lapply(L,pad.na,len=maxlen))
    }

    (no probado).

  4. 3

    Esto no es posible. Lo más cerca que se puede obtener es de llenar el «vacío» de los espacios con el valor NA.

    • hay una manera fácil de hacer esto?
  5. -1

    Problema Similar:

     coin <- c("Head", "Tail")
    toss <- sample(coin, 50, replace=TRUE)
    
    categorize <- function(x,len){
      count_heads <- 0
      count_tails <- 0
      tails <- as.character()
      heads <- as.character()
      for(i in 1:len){
        if(x[i] == "Head"){
          heads <- c(heads,x[i])
          count_heads <- count_heads + 1
        }else {
          tails <- c(tails,x[i])
          count_tails <- count_tails + 1
        }
      }
      if(count_heads > count_tails){
        head <- heads
        tail <- c(tails, rep(NA, (count_heads-count_tails)))
      } else {
        head <- c(heads, rep(NA,(count_tails-count_heads)))
        tail <- tails
      }
      data.frame(cbind("Heads"=head, "Tails"=tail))
    }

    categorizar(lanzar,50)

    De salida:
    Después de la sacudida de la moneda será el 31 de Cabeza y 19 de la Cola. A continuación, el resto de la cola se llena de NA con el fin de hacer un marco de datos.

    • El cultivo de plantas en un bucle es una mala idea en R, la costumbre de referencia es http://www.burns-stat.com/documents/books/the-r-inferno/ Usted puede hacer heads = sum(x == "Head"), ¿verdad? Realmente, supongo que rbinom tendría más sentido que sample en cualquier caso.

Dejar respuesta

Please enter your comment!
Please enter your name here