r dataframe write.table

Lista de tipos no implementados al intentar escribir.



dataframe write.table (6)

Tengo el siguiente data.table (data.frame) llamado salida:

> head(output) Id Title IsProhibited 1 10000074 Renault Logan, 2005 0 2 10000124 Ñêëàäñêîå ïîìåùåíèå, 345 ì<U+00B2> 0 3 10000175 Ñó-øåô 0 4 10000196 3-ê êâàðòèðà, 64 ì<U+00B2>, 3/5 ýò. 0 5 10000387 Samsung galaxy S4 mini GT-I9190 (÷¸ðíûé) 0 6 10000395 Êàðòèíà ""Êðûì. Ïîñåëîê Àðîìàò"" (õîëñò, ìàñëî) 0

Estoy tratando de exportarlo a un CSV así:

> write.table(output, ''output.csv'', sep = '','', row.names = FALSE, append = T)

Sin embargo, al hacerlo me sale el siguiente error:

Error in .External2(C_writetable, x, file, nrow(x), p, rnames, sep, eol, : unimplemented type ''list'' in ''EncodeElement'' In addition: Warning message: In write.table(output, "output.csv", sep = ",", row.names = FALSE, : appending column names to file

He intentado convertir el Title en una cadena para que ya no sea de tipo de list como así:

toString(output$Title)

Pero, me sale el mismo error. Mis tipos son:

> class(output) [1] "data.frame" > class(output$Id) [1] "integer" > class(output$Title) [1] "list" > class(output$IsProhibited) [1] "factor"

¿Puede alguien decirme cómo puedo exportar mi data.frame a CSV?

Otra cosa extraña que he notado, es que si escribo head(output) mi texto no está codificado correctamente (como se muestra arriba), mientras que si escribo la output$Title[0:3] , se mostrará el texto correctamente. :

> output$Title[0:3] [[1]] [1] "Renault Logan, 2005" [[2]] [1] "Складское помещение, 345 м²" [[3]] [1] "Су-шеф"

¿Alguna idea con respecto a eso? ¿Es relevante para mi problema inicial?

Edición: Aquí está mi nueva salida:

Id Title IsProhibited 10000074 Renault Logan, 2005 0 10000124 СкладÑкое помещение, 345 м<U+00B2> 0 10000175 Су-шеф 0 10000196 3-к квартира, 64 м<U+00B2>, 3/5 ÑÑ‚. 0 10000387 Samsung galaxy S4 mini GT-I9190 (чёрный) 0 10000395 Картина //"Крым. ПоÑелок Ðромат/"/" (холÑÑ‚ маÑло)" 0 10000594 КальÑн 25 Ñм 0 10000612 1-к квартира, 45 м<U+00B2>, 6/17 ÑÑ‚. 0 10000816 Гараж, 18 м<U+00B2> 0 10000831 Платье 0 10000930 Карбюраторы К-22И, К-22Г от газ 21 и газ 51 0

¿Observe cómo se enreda la línea de identificación 10000395? Parece que contiene citas propias que están arruinando el CSV. ¿Cómo puedo arreglar eso?


Asumiendo

  • la ruta que desea guardar es la Path , es decir, la path=Path

  • df es el marco de datos que desea guardar,

siga esos pasos:

  1. Guardar df como documento txt :

    write.table(df,"Path/df.txt",sep="|")

  2. Lea el archivo de texto en R:

    Data = read.table("Path/df.txt",sep="|")

  3. Ahora guarda como csv :

    write.csv(Data, "Path/df.csv")

Eso es.


Como se mencionó en los comentarios, deberías poder hacer algo como esto (sin probar) para "aplanar" tu list en un vector de caracteres:

output$Title <- vapply(output$Title, paste, collapse = ", ", character(1L))

Como también se mencionó, si quisiera probar el enfoque de no unlist , podría "expandir" cada fila por los valores individuales en la output$Title , algo como esto:

x <- vapply(output$Title, length, 1L) ## How many items per list element output <- output[rep(rownames(output), x), ] ## Expand the data frame output$Title <- unlist(output$Title, use.names = FALSE) ## Replace with raw values


Esas son todas las soluciones elegantes.

Para el lector curioso que preferiría un código R a paquetes ya preparados, aquí hay una función R que devuelve un marco de datos que no se encuentra en la lista que se puede exportar y guardar como .csv.

La salida es el marco de datos "problemático" en cuestión.

df_unlist<-function(df){ df<-as.data.frame(df) nr<-nrow(df) c.names<-colnames(df) lscols<-as.vector(which(apply(df,2,is.list)==TRUE)) if(length(lscols)!=0){ for(i in lscols){ temp<-as.vector(unlist(df[,i])) if(length(temp)!=nr){ adj<-nr-length(temp) temp<-c(rep(0,adj),temp) } df[,i]<-temp } #end for df<-as.data.frame(df) colnames(df)<-c.names } return(df) }

Aplicar la función en el marco de datos "salida":

newDF<-df_unlist(output)

A continuación, puede confirmar que el nuevo marco de datos (newDF) no está "listado" a través de apply (). Esto debería devolver FALSO con éxito.

apply(newDF,2,is.list) #2 for column-wise step.

Continúe para guardar el nuevo marco de datos, newDF como archivo .csv en la ruta que elija.

write.csv(newDF,"E:/Data/newDF.csv")


Haga esto, independientemente de cuántas columnas tenga:

df <- apply(df,2,as.character)

Entonces haz write.csv .


Hay una nueva función (introducida en noviembre de 2016) en el paquete data.table que maneja la escritura de un objeto data.table en csv bastante bien, incluso en aquellos casos en que una columna de data.table es una lista.

fwrite(data.table, file ="myDT.csv")


Otra solución fácil. Tal vez una o más columnas son de tipo list , por lo que necesitamos convertirlas a "caracteres" o marco de datos. Así que hay dos soluciones fáciles.

  1. Convierta cada columna "como.caracter" usando--

    df$col1 = as.character(df$col1)

    df$col2 = as.character(df$col2)

    .......y así

  2. El mejor convertir df en una "matriz"

    df = as.matrix(df)

ahora escribe df en csv. Funciona para mi.