51

我有以下称为输出的data.table(data.frame):

> 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

我正在尝试将其导出为 CSV,如下所示:

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

但是,这样做时,我收到以下错误:

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

我尝试将其转换Title为字符串,使其不再是list这样的类型:

toString(output$Title)

但是,我得到同样的错误。我的类型是:

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

谁能告诉我如何将我的 data.frame 导出为 CSV?

我注意到的另一件奇怪的事情是,如果我写head(output)的文本没有正确编码(如上所示),而如果我只是写output$Title[0:3]它会正确显示文本,如下所示:

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

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

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

有什么想法吗?它与我最初的问题有关吗?

编辑:这是我的新输出:

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   

请注意行 ID 10000395 是如何搞砸的?它似乎包含它自己的引号,这些引号弄乱了 CSV。我该如何解决?

4

6 回答 6

54

执行此操作,无论您有多少列:

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

然后做write.csv

于 2016-11-29T06:22:44.367 回答
30

正如评论中提到的,你应该能够做这样的事情(未经测试)来将你“扁平化”list成一个字符向量:

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

如前所述,如果您想尝试该unlist方法,可以通过 中的单个值“扩展”每一行output$Title,如下所示:

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
于 2014-07-18T16:07:44.987 回答
21

data.table 包中有一个新函数(2016 年 11 月引入),可以很好地处理将 data.table 对象写入 csv,即使在 data.table 的列是列表的情况下也是如此。

fwrite(data.table, file ="myDT.csv")
于 2017-03-14T11:43:05.390 回答
9

另一个简单的解决方案。也许一列或多列是 type list,所以我们需要将它们转换为“字符”或数据框。所以有两个简单的解决方案

  1. 使用--转换每一列“as.character”

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

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

    .......等等

  2. 最好的转换成df“矩阵”

    df = as.matrix(df)

现在写入dfcsv。为我工作。

于 2016-08-04T06:53:04.847 回答
1

这些都是优雅的解决方案。

对于喜欢一些 R 代码而不是现成包的好奇读者,这里有一个 R 函数,它返回一个可以导出并保存为 .csv 的非列表数据帧。

输出是有问题的“麻烦”数据框。

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

在数据框“输出”上应用该功能:

newDF<-df_unlist(output)

接下来,您可以通过 apply() 确认新的 (newDF) 数据框未“列出”。这应该成功返回 FALSE。

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

继续将新数据框 newDF 作为 .csv 文件保存到您选择的路径。

write.csv(newDF,"E:/Data/newDF.csv")
于 2018-08-31T20:28:20.980 回答
0

假设

  • 您要保存到的路径是Path,即path=Path

  • df是您要保存的数据框,

请按照以下步骤操作:

  1. 另存dftxt文档:

    write.table(df,"Path/df.txt",sep="|")
    
  2. 将文本文件读入 R:

    Data = read.table("Path/df.txt",sep="|")
    
  3. 现在另存为csv

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

而已。

于 2018-08-30T21:50:13.737 回答