Seite 1 von 1
CSV-Dateien aneinanderreihen
Verfasst: Do Nov 16, 2017 8:30 am
von schu
Liebes R-Forum,
ich möchte in R gerne 394 .csv-Dateien miteinander verknüpfen und am Ende eine vollständige .csv-Datei erhalten.
Die Dateien sind in ihrer Struktur identisch. Sie bestehen jeweils aus 5 Spalten (Jahr, Nation, Insgesamt, Männlich, Weiblich). Da die ersten beiden Spalten (Jahr, Nation) für alle Dateien gleich sind, sollen sie nur einmal in der endgültigen Datei stehen. Die Werte für die drei weiteren Spalten, sollen von links nach rechts hintereinander geschrieben werden. Dabei wäre es wünschenswert, wenn die ersten 14 Zeilen und Zeile 17 der .csv-Dateien einfach missachtet werden, da diese Informationen nicht benötigt werden.
Meine bisherigen Recherchen und Versuche haben mich dahin gebracht, dass ich die Dateinamen zunächst alle in ein Objekt speicher und anschließend über den Befehl "rbind" aneinanderreihe. Leider werden die Dateien dabei alle untereinander geschrieben. Das sieht so aus:
Code: Alles auswählen
## Dateinamen in Objekt speichern
filenames <- list.files(path = "mergetest/", full.names = F)
## Read.csv für alle Dateien in filenames ausführen
test1 <- do.call("rbind", lapply(filenames, read.csv2, header = F))
Der "cbind" Befehl, welcher Objekte in Spalten nebeneinander schreibt gibt folgenden Fehler aus:
Code: Alles auswählen
Error in data.frame(..., check.names = FALSE) :
Argumente implizieren unterschiedliche Anzahl Zeilen: 1768, 3535
Die .csv-Dateien haben jedoch alle 3535 Zeilen. Das habe ich für meine 10 Testdokumente nachgesehen.
Ich danke vorab für jede Hilfe!
Viele Grüße
Sebastian
Re: CSV-Dateien aneinanderreihen
Verfasst: Do Nov 16, 2017 2:00 pm
von EDi
Bitte ein reproduzierbares Beispiel posten (z.B. 2dateien).
Auch ist mir noch nicht klar wie die endgültige Tabelle aussehen soll.
Re: CSV-Dateien aneinanderreihen
Verfasst: Do Nov 16, 2017 4:40 pm
von schu
Anbei die zwei Dateien und ein Screenshot, der zeigt, wie die finale .csv aussehen soll. Es wäre schön, ist aber nicht unbedingt nötig, dass in der finalen .csv-Datei die Leerzeilen nicht mehr vorhanden sind.
Ich hoffe es wird damit etwas klarer.
https://picload.org/view/droigorw/finalecsv.png.html
Viele Grüße
Sebastian
Re: CSV-Dateien aneinanderreihen
Verfasst: Do Nov 16, 2017 9:28 pm
von EDi
Anbei die zwei Dateien und ein Screenshot, der zeigt, wie die finale .csv aussehen soll.
OK, bevor du dich an das bearbeiten mehrere Dateien zuwendest, solltest du zuerst mal schauen eine einzelne Datein in ein gescheites Format umzuormatieren. [Das format ist ziemlich schrottig...]
Was hast du denn da schon probiert?
?read.table. "skip" könnte schonmal nützlich sein...
Re: CSV-Dateien aneinanderreihen
Verfasst: Fr Nov 17, 2017 1:51 pm
von schu
[Das format ist ziemlich schrottig...]
Wie meinst Du das? Findest Du das Ausgangsformat schrottig, oder wie ich es mir am Ende vorstelle?
Ich habe eine der Dateien jetzt wie folgt umformatiert und das kommt meiner Wunschvorstellung schon sehr nahe:
Code: Alles auswählen
table1 <- read.csv(file = "mergetest/einw05974044.csv",
header = T,
sep = ";",
skip = 8,
nrows = 1751,
blank.lines.skip = T,
na.strings = c("-", "."),
col.names = c("Jahr", "Region", "insgesamt", "männlich", "weiblich"))
Was fehlt ist, dass die Nummer aus dem Dateinamen (hier: 05974044) in den drei Spalten "insgesamt", "männlich" und "weiblich" an den Anfang geschrieben wird, so dass die Spalten am Ende "05974044insgesamt", usw. heißen. Ist es anschließend möglich das ganze als Funktion zu definieren und über alle Dateien im Objekt filenames (s. erster Post) laufen zu lassen? Oder denke ich da gerade falsch?
Re: CSV-Dateien aneinanderreihen
Verfasst: So Nov 19, 2017 7:26 pm
von EDi
Wie meinst Du das? Findest Du das Ausgangsformat schrottig, oder wie ich es mir am Ende vorstelle?
Eingangsformat... Hat mehrere Probleme...
Hier eine Möglichkeit beide Dateien einzulesen (mit einpaar extra Schritten die nicht zwingend notwenig sind...):
Code: Alles auswählen
files <- list.files('Downloads/', pattern = 'einw.*\\.csv', full.names = TRUE)
# apply / develop data cleaning pipeline for one file -----------------------
tab <- read.table(file = files[1],
header = FALSE,
sep = ";",
as.is = TRUE,
na.strings = c("-", ".", ""),
fill = TRUE,
blank.lines.skip = FALSE)
# remove header rows
tab <- tab[-c(1:which(tab$V3 == "Personen")), ]
# remove tail rows
tab <- tab[-c(min(which(tab$V1 == "_____"), nrow(tab))), ]
# set colnames
colnames(tab) <- c("Jahr", "Region", "insgesamt", "männlich", "weiblich")
# remove empty rows
tab <- tab[!is.na(tab$insgesamt), ]
# fill NAs with zero
tab$männlich[is.na(tab$männlich)] <- 0
tab$weiblich[is.na(tab$weiblich)] <- 0
# make numeric
tab$männlich <- as.numeric(tab$männlich)
tab$weiblich <- as.numeric(tab$weiblich)
tab$insgesamt <- as.numeric(tab$insgesamt)
# check if all are equal
all(tab$männlich + tab$weiblich == tab$insgesamt)
# remove redundant information
tab$insgesamt <- NULL
# bring to long format
library(tidyr)
tab <- gather(tab, 'geschlecht', 'anzahl', -Jahr, - Region)
head(tab)
# Warp into function and apply to all files -------------------------------
clean_file <- function(file) {
tab <- read.table(file = file,
header = FALSE,
sep = ";",
as.is = TRUE,
na.strings = c("-", ".", ""),
fill = TRUE,
blank.lines.skip = FALSE)
# remove header rows
tab <- tab[-c(1:which(tab$V3 == "Personen")), ]
# remove tail rows
tab <- tab[-c(min(which(tab$V1 == "_____"), nrow(tab))), ]
# set colnames
colnames(tab) <- c("Jahr", "Region", "insgesamt", "männlich", "weiblich")
# remove empty rows
tab <- tab[!is.na(tab$insgesamt), ]
# fill NAs with zero
tab$männlich[is.na(tab$männlich)] <- 0
tab$weiblich[is.na(tab$weiblich)] <- 0
# make numeric
tab$männlich <- as.numeric(tab$männlich)
tab$weiblich <- as.numeric(tab$weiblich)
tab$insgesamt <- as.numeric(tab$insgesamt)
# check if all are equal
if(!all(tab$männlich + tab$weiblich == tab$insgesamt)) {
warning('File ', file, 'has non-consistent data!')
}
# remove redundant information
tab$insgesamt <- NULL
# bring to long format
tab <- gather(tab, 'geschlecht', 'anzahl', -Jahr, - Region)
# set filename in column
tab$source <- file
return(tab)
}
# check function
clean_file(files[2])
# apply function to each file and store in list
cleaned_files <- lapply(files, clean_file)
# combine all tables into one
do.call(rbind, cleaned_files)
Re: CSV-Dateien aneinanderreihen
Verfasst: Mo Nov 20, 2017 12:14 pm
von schu
Vielen Dank für deinen Lösungsansatz EDi

. Es löst mein Problem, auch wenn ich es mir etwas anders vorgestellt habe und einigen der Befehle nicht ganz folgen kann.
Re: CSV-Dateien aneinanderreihen
Verfasst: Mo Nov 20, 2017 6:42 pm
von EDi
schu hat geschrieben: Mo Nov 20, 2017 12:14 pm
Vielen Dank für deinen Lösungsansatz EDi

. Es löst mein Problem, auch wenn ich es mir etwas anders vorgestellt habe und einigen der Befehle nicht ganz folgen kann.
Na dann, Zeile für Zeile durchgehen, schauen was passiert und eventuell modifizieren.