Unimplemented type list when trying to write.table

RDataframewrite.table

R Problem Overview


I have the following data.table (data.frame) called output:

> 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

I am trying to export it to a CSV like so:

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

However, when doing so I get the following 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

I have tried converting the Title to a string so that it is no longer of type list like so:

toString(output$Title)

But, I get the same error. My types are:

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

Can anyone tell me how I can export my data.frame to CSV?

Another strange thing that I've noticed, is that if I write head(output) my text is not encoded properly (as shown above) whereas if I simply write output$Title[0:3] it will display the text correctly like so:

> output$Title[0:3]
[[1]]
[1] "Renault Logan, 2005"

[[2]]
[1] "Складское помещение, 345 м²"

[[3]]
[1] "Су-шеф"

Any ideas regarding that? Is it relevant to my initial problem?

Edit: Here is my new output:

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	

Notice how line ID 10000395 is messed up? It seems to contains quotes of it's own which are messing up the CSV. How can I fix that?

R Solutions


Solution 1 - R

Do this, irrespective of how many columns you have:

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

Then do write.csv.

Solution 2 - R

As mentioned in the comments, you should be able to do something like this (untested) to get "flatten" your list into a character vector:

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

As also mentioned, if you wanted to try the unlist approach, you could "expand" each row by the individual values in output$Title, something like this:

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

Solution 3 - R

There is a new function (introduced in november 2016) in data.table package that handles writing a data.table object to csv quite well, even in those cases when a column of the data.table is a list.

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

Solution 4 - R

Another easy solution. Maybe one or more columns are of type list, so we need convert them to "character" or data frame. So there are two easy solutions

  1. Convert each column "as.character" using--

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

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

    .......and so on

  2. The best one convert df in to a "matrix"

    df = as.matrix(df)

now write df into csv. Works for me.

Solution 5 - R

Those are all elegant solutions.

For the curious reader who would prefer some R-code to ready made packages , here's an R-function that returns a non-list dataframe that can be exported and saved as .csv.

output is the "troublesome" data frame in question.

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)
}

Apply the function on dataframe "output" :

newDF<-df_unlist(output)

You can next confirm that the new (newDF) data frame is not 'listed' via apply(). This should successfully return FALSE.

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

Proceed to save the new dataframe, newDF as a .csv file to a path of your choice.

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

Solution 6 - R

Assuming

  • the path you want to save to is Path, i.e. path=Path

  • df is the dataframe you want to save,

follow those steps:

  1. Save df as txt document:

    write.table(df,"Path/df.txt",sep="|")
    
  2. Read the text file into R:

    Data = read.table("Path/df.txt",sep="|")
    
  3. Now save as csv:

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

That's it.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1477388View Question on Stackoverflow
Solution 1 - RShalini BaranwalView Answer on Stackoverflow
Solution 2 - RA5C1D2H2I1M1N2O1R2T1View Answer on Stackoverflow
Solution 3 - RllrsView Answer on Stackoverflow
Solution 4 - RRavi kumarView Answer on Stackoverflow
Solution 5 - Ruser10187691View Answer on Stackoverflow
Solution 6 - Ruser10187691View Answer on Stackoverflow