web-dev-qa-db-fra.com

Liste de types non implémentée en essayant d'écrire.table

J'ai le data.table suivant (data.frame) appelé 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

J'essaie de l'exporter vers un fichier CSV comme ceci:

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

Cependant, ce faisant, j'obtiens le message d'erreur suivant:

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

J'ai essayé de convertir le Title en une chaîne de sorte qu'il ne soit plus du type list comme ceci:

toString(output$Title)

Mais je reçois la même erreur. Mes types sont:

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

Quelqu'un peut-il me dire comment exporter mon data.frame au format CSV?

Une autre chose étrange que j'ai remarquée est que si j'écris head(output), mon texte n'est pas codé correctement (comme indiqué ci-dessus), alors que si j'écris simplement output$Title[0:3], le texte s'affichera correctement de la manière suivante:

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

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

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

Des idées à ce sujet? Est-ce pertinent pour mon problème initial?

Edit: Voici ma nouvelle sortie:

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   

Remarquez comment l'ID de ligne 10000395 est foiré? Il semble contenir des citations personnelles qui dérangent le CSV. Comment puis-je résoudre ce problème?

26
user1477388

Comme mentionné dans les commentaires, vous devriez pouvoir faire quelque chose comme ceci (non testé) pour "aplatir" votre list dans un vecteur de caractère:

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

Comme mentionné également, si vous souhaitez essayer l'approche unlist, vous pouvez "développer" chaque ligne en fonction des valeurs individuelles dans output$Title, comme ceci:

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
19

Faites cela, quel que soit le nombre de colonnes que vous avez:

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

Alors faites write.csv.

17
Shalini Baranwal

Il existe une nouvelle fonction (introduite en novembre 2016) dans le package data.table qui gère très bien l'écriture d'un objet data.table sur csv, même dans les cas où une colonne de data.table est une liste.

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

En supposant

  • le chemin que vous souhaitez enregistrer est Path, c.-à-d. path=Path

  • df est le dataframe que vous voulez sauvegarder,

suivez ces étapes:

  1. Enregistrer df sous txt document:

    write.table(df,"Path/df.txt",sep="|")
    
  2. Lire le fichier texte dans R:

    Data = read.table("Path/df.txt",sep="|")
    
  3. Maintenant, enregistrez sous csv :

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

C'est tout.

1
K.Pascal

Ce sont toutes des solutions élégantes. 

Pour les lecteurs curieux qui préféreraient certains codes R à des packages prêts à l'emploi, voici une fonction R qui renvoie un cadre de données non répertorié pouvant être exporté et enregistré au format .csv.

la sortie est la trame de données "problématique" en 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)
}

Appliquez la fonction sur la structure de données "sortie":

newDF<-df_unlist(output)

Vous pouvez ensuite confirmer que le nouveau bloc de données (newDF) n'est pas "répertorié" via apply (). Cela devrait retourner FALSE avec succès.

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

Enregistrez ensuite le nouveau cadre de données, newDF en tant que fichier .csv dans le chemin de votre choix.

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