Seite 1 von 1

Daten formatieren und in spalten trennen

Verfasst: Do Aug 15, 2019 2:51 pm
von ad_berlin
Hi, ich habe eine Spalte (properties) in einem Datensatz die in etwas wie folgt aussieht:

properties
,"{'gender': 'Female', 'document_type': 'driving_licence', 'date_of_expiry': '2023-02-28', 'issuing_country': 'GBR'}",
,"{'document_type': 'driving_licence', 'date_of_expiry': '2044-12-14', 'issuing_country': 'GRC'}",
,"{'gender': 'Male', 'document_type': 'driving_licence', 'date_of_expiry': '2019-06-11', 'issuing_country': 'GBR'}",
,"{'gender': 'Female', 'document_type': 'driving_licence', 'date_of_expiry': '2023-12-06', 'issuing_country': 'GBR'}",

die eintrage in properties sind also nicht alle gleich. Ich würde die spalte gerne so formatieren das sie am ende so aussieht

gender, doc_type, doe, country,
female, driving_license, 2023-02-28, GBR,

usw....

kann mir jemand sagen wie ich das am besten mache?

Re: Daten formatieren und in spalten trennen

Verfasst: Do Aug 15, 2019 3:59 pm
von bigben
Hallo ad_berlin,

für mich sieht das so aus, als wäre Dein Eingabeformat JSON. Ist das so? Dann müsste man das Rad nicht neu erfinden und könnte auf ein package für JSON zurückgreifen.
Sowas zum Beispiel https://www.tutorialspoint.com/r/r_json_files bzw. https://cran.r-project.org/web/packages ... index.html

LG,
Bernhard

Re: Daten formatieren und in spalten trennen

Verfasst: Do Aug 15, 2019 5:34 pm
von ad_berlin
Moin Bernhard,

danke für die prompte Hilfe. Ich bin ein kleines Stück weiter gekommen habe folgendes gemacht:

Die spalte "kopiert"
json_properties <- doc_report$properties

Dann wollte ich mit:
json_properties <- fromJSON(json_properties)

das ganze konvertieren. Bekam jedoch den Fehler:
Error in fromJSON(json_properties) :
STRING_ELT() can only be applied to a 'character vector', not a 'integer'

also habe ich einen string draus gemacht:
toString(json_properties)

der Fehler bleibt jedoch auch danach der gleiche.

Dann habe ich noch ausprobiert es in einen data.frame zu konvertieren mit:
json_properties <- as.data.frame(json_properties)

das klappt aber bringt nicht wirklich was.

Auf dem ersten link den du geschickt hast ist das format auch etwas anders. Meinst du mein format ist tatsächlich json?


hier nochmal wie das bei mir aussieht nachdem ich die spalte in einen son file ausgegeben habe:
"","x"
"1","{'gender': 'Male', 'nationality': 'IRL', 'document_type': 'passport', 'date_of_expiry': '2019-08-12', 'issuing_country': 'IRL'}"
"2","{'gender': 'Female', 'document_type': 'driving_licence', 'date_of_expiry': '2023-02-28', 'issuing_country': 'GBR'}"
"3","{'gender': 'Male', 'nationality': 'ITA', 'document_type': 'passport', 'date_of_expiry': '2018-06-09', 'issuing_country': 'ITA'}"
"4","{'gender': 'Male', 'issuing_date': '2007-08', 'document_type': 'national_identity_card', 'issuing_country': 'FRA'}"
"5","{'gender': 'Male', 'nationality': 'POL', 'document_type': 'national_identity_card', 'date_of_expiry': '2019-05-29', 'issuing_country': 'POL'}"
"6","{'gender': 'Male', 'nationality': 'BRA', 'document_type': 'passport', 'date_of_expiry': '2027-01-04', 'issuing_country': 'BRA'}"
"7","{'gender': 'Male', 'nationality': 'ESP', 'document_type': 'national_identity_card', 'date_of_expiry': '2019-04-03', 'issuing_country': 'ESP'}"
"8","{'gender': 'Male', 'document_type': 'driving_licence', 'date_of_expiry': '2023-11-20', 'issuing_country': 'GBR'}"
"9","{'gender': 'Male', 'document_type': 'driving_licence', 'date_of_expiry': '2021-01-18', 'issuing_country': 'GBR'}"
"10","{'gender': 'Male', 'document_type': 'driving_licence', 'date_of_expiry': '2023-07-25', 'issuing_country': 'GBR'}"
use...

Re: Daten formatieren und in spalten trennen

Verfasst: Do Aug 15, 2019 11:38 pm
von EDi
Das ist kein valides JSON (wegen den single-quotes):http://www.json.org/

Wieso hast du denn ein Vektor von JSONs? I
Ich vermute das Problem liegt weiter vorne...

Trotzem hier eine Lösung:
quotes fixen und mit purrr::map_df über den Vektor laufen und das JSON einlesen.

Code: Alles auswählen

d <- c("{'gender': 'Male', 'nationality': 'IRL', 'document_type': 'passport', 'date_of_expiry': '2019-08-12', 'issuing_country': 'IRL'}",
       "{'gender': 'Female', 'document_type': 'driving_licence', 'date_of_expiry': '2023-02-28', 'issuing_country': 'GBR'}")

# change single by double qoute
d <- gsub('\'', '"', d)

library(jsonlite)
library(purrr)

map_df(d, fromJSON)

Re: Daten formatieren und in spalten trennen

Verfasst: Fr Aug 16, 2019 10:56 am
von ad_berlin
Hi Bernhard, nochmals vielen vielen Dank.

Mit deinem c() klappt das super mit meiner spalte leider irgendwie nicht.

folgendes habe ich gemacht:

Code: Alles auswählen

> #Load !!!Change Path!!!:
> doc_report <- read.csv("doc_reports.csv", header = TRUE)
> d <- c(doc_report$properties)
> # change single by double qoute
> d <- gsub('\'', '"', d)
> library(jsonlite)
> library(purrr)
> library(dplyr)
> map_df(d, fromJSON)
Error: Argument 1 must have names
Auf jeden fall bekomme ich den error.

Ich bin noch etwas frisch mir R aber der error bezieht sich doch auf das "d" in der map_df function, oder?

EDIT:

wenn ich mir den head(d) anschaue bekomme ich außerdem folgendes:

Code: Alles auswählen

> 
head(d)
[1] "57857" "5130"  "59667" "34937" "65694" "44613"
EDIT 2:

ok das

Code: Alles auswählen

d <- c(doc_report$properties)
ist wohl schonmal falsch
wenn ich stattdessen aber das c weglasse bekomme ich folgenden Fehler:

Code: Alles auswählen

> map_df(d, fromJSON)
Error: lexical error: invalid char in json text.
                            {"gender": None, "issuing_date": "2007-07-
                     (right here) ------^
Edit 3:

Code: Alles auswählen

d <- gsub('None', '"None"', d)
es funktioniert! 1000 dank Bernhard.

EDIT 4:
doch noch nicht ganz.
es gibt Zeilen in den steht nur {}.
Die werden nach dem fromJSON Befehl gelöscht. Was nicht so gut ist, da ich das ganze ja später wieder an meinen eigentlichen df anhängen möchte.
Nun dachte ich
- ich führe alle befehle in dem eigentlich df aus. Funktioniert leider nicht.
- ich ersetze {} mit {NA} geht d <- gsub("\{\}", "\{NA\}", d) geht leider auch nicht
-

Re: Daten formatieren und in spalten trennen

Verfasst: Fr Aug 16, 2019 12:25 pm
von bigben
ad_berlin hat geschrieben: Fr Aug 16, 2019 10:56 ames funktioniert! 1000 dank Bernhard.
Lieb gemeint, aber der Dank geht an Eduard aka EDi, nicht an mich.

LG,
Bernhard

Re: Daten formatieren und in spalten trennen

Verfasst: Fr Aug 16, 2019 12:33 pm
von ad_berlin
oh sorry nicht gesehen vielen dank Edi.

vielleicht kann noch Jed mit meinem edit 4 helfen:
EDIT 4:
doch noch nicht ganz.
es gibt Zeilen in den steht nur {}.
Die werden nach dem fromJSON Befehl gelöscht. Was nicht so gut ist, da ich das ganze ja später wieder an meinen eigentlichen df anhängen möchte.
Nun dachte ich
- ich führe alle befehle in dem eigentlich df aus. Funktioniert leider nicht.
- ich ersetze {} mit {NA} geht d <- gsub("\{\}", "\{NA\}", d) geht leider auch nicht
das klappt leider auch nicht

Code: Alles auswählen

> d <- gsub("{}", "{\"gender\": \"NA\", \"nationality\": \"NA\", \"document_type\": \"passport\", \"date_of_expiry\": \"2019-08-12\", \"issuing_country\": \"NA\"}" , d)
Error in gsub("{}", "{\"gender\": \"NA\", \"nationality\": \"NA\", \"document_type\": \"passport\", \"date_of_expiry\": \"2019-08-12\", \"issuing_country\": \"NA\"}",  : 
  invalid regular expression '{}', reason 'Invalid contents of {}'
wie kann ich dem denn sagen, dass die klammern leer sind?

Edit 5:
den befell hab ich gefunden. man muss eckige klammern drum machen.

Code: Alles auswählen

d <- gsub('[{}]', '{\"gender\": \"NA\", \"nationality\": \"NA\", \"document_type\": \"passport\", \"date_of_expiry\": \"2019-08-12\", \"issuing_country\": \"NA\"}' , d)
jedoch kommt das dabei raus:

Code: Alles auswählen

[1] "{\"gender\": \"NA\", \"nationality\": \"NA\", \"document_type\": \"passport\", \"date_of_expiry\": \"2019-08-12\", \"issuing_country\": \"NA\"}\"gender\": \"Male\", \"nationality\": \"IRL\", \"document_type\": \"passport\", \"date_of_expiry\": \"2019-08-12\", \"issuing_country\": \"IRL\"{\"gender\": \"NA\", \"nationality\": \"NA\", \"document_type\": \"passport\", \"date_of_expiry\": \"2019-08-12\", \"issuing_country\": \"NA\"}" 

Re: Daten formatieren und in spalten trennen

Verfasst: Fr Aug 16, 2019 3:59 pm
von EDi
Bitte ein reproduzierbares Beispiel einstellen.

Ich war so nett und hab es erstellt. Das hat (erwartungsgemäß) nicht zu deinem Fall gepasst.

Re: Daten formatieren und in spalten trennen

Verfasst: Fr Aug 16, 2019 4:09 pm
von ad_berlin
o.k. also ich hab mal ein paar lines kopiert (ich hoffe das passt so!?).

Code: Alles auswählen

"{\"gender\": \"Male\", \"nationality\": \"NZL\", \"document_type\": \"passport\", \"date_of_expiry\": \"2027-01-20\", \"issuing_country\": \"NZL\"}"                 
"{\"gender\": \"Female\", \"issuing_date\": \"2014-04-29\", \"document_type\": \"driving_licence\", \"date_of_expiry\": \"2015-10-04\", \"issuing_country\": \"GBR\"}"
"{\"gender\": \"Male\", \"document_type\": \"national_identity_card\", \"date_of_expiry\": \"2019-06-12\", \"issuing_country\": \"ESP\"}"                             
"{\"document_type\": \"driving_licence\", \"issuing_country\": \"POL\"}"                                                                                              
"{}"                                                                                                                                                                  
"{}"                                                                                                                                                                  
"{\"gender\": \"Female\", \"nationality\": \"ESP\", \"document_type\": \"national_identity_card\", \"date_of_expiry\": \"2022-09-03\", \"issuing_country\": \"ESP\"}"
 "{\"gender\": \"Female\", \"nationality\": \"PRT\", \"document_type\": \"national_identity_card\", \"date_of_expiry\": \"2018-12-22\", \"issuing_country\": \"PRT\"}" 
 "{\"gender\": \"Female\", \"nationality\": \"PRT\", \"document_type\": \"national_identity_card\", \"date_of_expiry\": \"2019-07-02\", \"issuing_country\": \"PRT\"}" 
alle schritte oben sind durch und haben funktioniert. der nächste wäre jetzt

Code: Alles auswählen

properties <- map_df(d, fromJSON)
dabei werden jedoch alle Zeilen mit nur {} gelöscht. das möchte ich nicht und würde sie gerne mit folgendem überschreiben:

Code: Alles auswählen

"{\"gender\": \"NA\", \"nationality\": \"NA\", \"document_type\": \"passport\", \"date_of_expiry\": \"2019-08-12\", \"issuing_country\": \"NA\"}"
dazu habe ich folgenden code benutzt:

Code: Alles auswählen

d <- gsub('[{}]', '{\"gender\": \"NA\", \"nationality\": \"NA\", \"document_type\": \"passport\", \"date_of_expiry\": \"2019-08-12\", \"issuing_country\": \"NA\"}' , d)
leider interpretiert er die einzelnen klammer und hängt das gewünschte vor und auch hinten an:

Code: Alles auswählen

"{\"gender\": \"NA\", \"nationality\": \"NA\", \"document_type\": \"passport\", \"date_of_expiry\": \"2019-08-12\", \"issuing_country\": \"NA\"}\"gender\": \"Female\", \"document_type\": \"driving_licence\", \"date_of_expiry\": \"2023-02-28\", \"issuing_country\": \"GBR\"{\"gender\": \"NA\", \"nationality\": \"NA\", \"document_type\": \"passport\", \"date_of_expiry\": \"2019-08-12\", \"issuing_country\": \"NA\"}"
hast du dafür zufällig eine Lösung?

hier nochmal der gesamte code:

Code: Alles auswählen

library(jsonlite)
library(purrr)
library(dplyr)
doc_report <- read.csv("~/Dropbox/Arbeit/Revolut/Test 2/Task 1 Files/doc_reports.csv", header = TRUE)
d <- doc_report$properties
d <- gsub('\'', '"', d)
d <- gsub('None', '"None"', d)
d <- gsub('[{}]', '{\"gender\": \"NA\", \"nationality\": \"NA\", \"document_type\": \"passport\", \"date_of_expiry\": \"2019-08-12\", \"issuing_country\": \"NA\"}' , d)

Re: Daten formatieren und in spalten trennen

Verfasst: Fr Aug 16, 2019 5:31 pm
von ad_berlin
ok, was für ein pain aber ich scheine eine Lösung gefunden zu haben für Dokumentationszecke poste ich sie hier mal:

Code: Alles auswählen

empty <- grep("\\{\\}", d)
d[empty] <- "{\"gender\": \"NA\", \"nationality\": \"NA\", \"document_type\": \"passport\", \"date_of_expiry\": \"2019-08-12\", \"issuing_country\": \"NA\"}"