2017-11-29 1 views
0

Ich habe ein Verzeichnis von Textdateien mit der folgenden Konvention benannt: "Location[A-Z]_House[0-15]_Day[0_15].txt", so ein Beispiel ist LA_H05_D14.txt. Gibt es eine Möglichkeit, die Namen so aufzuteilen, dass sie zu einem Faktor werden können? Genauer gesagt möchte ich den Buchstaben [A-Z] verwenden, der nach dem Standort kommt. Z.B. LB_H01_D01.txt wäre Standort "B" und alle Daten, die zu Standort B gehören, werden mit "B" gekennzeichnet?Importieren Sie mehrere TXT-Dateien in einen Datenrahmen und verwenden Sie einen Teil der Dateinamen als "ID"

Ich habe alle Daten aus den Dateien in einem Datenrahmen importiert:

l = list.files(patt="txt$", full.names = T) 
library(dplyr) 

Df = bind_rows(lapply(l, function(i) {temp <- read.table(i,stringsAsFactors = FALSE,sep=";"); 
setNames(temp, c("Date","Time","Timestamp","PM2_5(ug/m3)","AQI(US)","AQI(CN)","PM10(ug/m3)","Outdoor AQI(US)","Outdoor AQI(CN)","Temperature(C)","Temperature(F)","Humidity(%RH)","CO2(ppm)","VOC(ppb)" 
))}), .id = "id") 

Die Daten, wie dies mit einem „id“ -Spalte aussieht:

head(Df) 
    id  Date  Time Timestamp PM2_5(ug/m3) AQI(US) AQI(CN) PM10(ug/m3) Outdoor AQI(US) Outdoor AQI(CN) Temperature(C) Temperature(F) 
1 1 2017/10/17 20:31:38 1508272298  102.5  175  135   512    0    0    30   86.1 
2 1 2017/10/17 20:31:48 1508272308   93.6  171  124   477    0    0    30   86.1 
3 1 2017/10/17 20:31:58 1508272318   98.0  173  129   397    0    0    30   86.0 
4 1 2017/10/17 20:32:08 1508272328   98.0  173  129   422    0    0    30   86.0 
5 1 2017/10/17 20:32:18 1508272338  104.3  176  137   466    0    0    30   86.0 
6 1 2017/10/17 20:32:28 1508272348  101.6  175  134   528    0    0    30   86.0 
    Humidity(%RH) CO2(ppm) VOC(ppb) 
1   43  466  -1 
2   43  467  -1 
3   42  468  -1 
4   42  469  -1 
5   42  471  -1 
6   42  471  -1 
+0

Ich denke, der Grund, warum man nicht ein sehr sinnvollen „id“ -Spalte bekommen ist, dass die Liste von 'lapply' zurück nicht gestattet. Wenn Sie 'bind_rows (setNames (lapply (l, ...), l), .id =" id ") verwenden, sollte es funktionieren. Danach können Sie den relevanten Teil des Dateinamens extrahieren. –

+1

Mögliches Duplikat: https://Stackoverflow.com/q/34313895 – Jaap

+1

Auch verwandt: https://Stackoverflow.com/q/32888757 – Jaap

Antwort

2

Unabhängig von der Frage über die Inhalt der ID-Spalte Sie könnten den folgenden Code verwenden, um die Informationen aus den Dateinamen zu extrahieren:

#you may use the original filenames 
filenames <- basename(l) 
#or the content of the id column 
filenames <- as.character(Df$id) #if you have read in filenames in the Df 
#for demonstration here a definition of exemplary filenames 
filenames <- c("LA_H01_D01.txt" 
       ,"LA_H02_D02.txt" 
       ,"LD_H01_D14.txt" 
       ,"LD_H01_D15.txt") 

filenames <- gsub("_H|_D", "_", filenames) 
filenames <- gsub(".txt|^L", "", filenames) 

fileinfo <- as.data.frame(do.call(rbind, strsplit(filenames, "_"))) 
colnames(fileinfo) <- c("Location", "House", "Day") 

fileinfo[, c("House", "Day")] <- apply(fileinfo[, c("House", "Day")], 2, as.numeric) 
#  Location House Day 
# 1  A  1 1 
# 2  A  2 2 
# 3  D  1 14 
# 4  D  1 15 

#add the information to your Df as new columns 
Df <- cbind(Df, fileinfo) 

#the whole thing as a function used in your data import 
add_fileinfo <- function(df, filename) { 

    filename <- gsub("_H|_D", "_", filename) 
    filename <- gsub(".txt|^L", "", filename) 

    fileinfo <- as.data.frame(do.call(rbind, strsplit(filename, "_"))) 
    colnames(fileinfo) <- c("Location", "House", "Day") 

    fileinfo[, c("House", "Day")] <- apply(fileinfo[, c("House", "Day")], 2, as.numeric) 

    cbind(df, fileinfo[rep(seq_len(nrow(fileinfo)), each= nrow(df)),]) 

} 

Df = bind_rows(lapply(l, function(i) 
{temp <- read.table(i,stringsAsFactors = FALSE,sep=";"); 
setNames(temp, c("Date","Time","Timestamp","PM2_5(ug/m3)","AQI(US)","AQI(CN)","PM10(ug/m3)","Outdoor AQI(US)","Outdoor AQI(CN)","Temperature(C)","Temperature(F)","Humidity(%RH)","CO2(ppm)","VOC(ppb)" 
)); 
temp <- add_fileinfo(temp, i); 
} 
), .id = "id") 
+0

Vielen Dank dafür. Die Dateien heißen "LA_H05_D14.txt" und wenn wir das teilen, verlieren wir einige Informationen bezüglich des Ortes. D – HCAI

+1

Ich habe meine Antwort als Antwort auf deinen Kommentar bearbeitet, sie sollte jetzt mit deinen Dateinamen arbeiten. Sag mir, wenn nicht. Alle Arten von Kombinationen von Wörtern und Ziffern können einfach mit Regex gehandhabt werden, wenn Sie komplexere Formate haben. –

+0

OOOH das sieht cool aus! Scheint, dass gsub wirklich mächtig ist! Das einzige, worüber ich jetzt stolpere ist, dass fileinfo 116 Zeilen hat, aber Df 96000, weil jede Datei, die ich importierte, viele hundert Zeilen hatte. Was denkst du darüber? – HCAI

1

Etwas wie diese (generische) Lösung sollte dich in Gang bringen.

mydata1 = read.csv(path1, header=T) 
mydata2 = read.csv(path2, header=T) 

Dann fusionieren

myfulldata = merge(mydata1, mydata2) 

Solange mydata1 und mydata2 mindestens eine gemeinsame Spalte mit einem identischen Namen haben (das die Beobachtungen in mydata1 Beobachtungen in mydata2 entspricht), wird dies wie Arbeit Ein Zauber. Es dauert auch drei Zeilen.

Was ist, wenn ich 20 Dateien mit Daten habe, die ich Beobachtung-zur-Beobachtung zuordnen möchte? Angenommen, sie haben alle eine gemeinsame Spalte, die das Zusammenführen ermöglicht, müsste ich immer noch 20 Dateien in (20 Zeilen Code) lesen und merge() arbeitet paarweise ... also könnte ich die 20 Datenrahmen zusammen mit 19 Zusammenführungs-Anweisungen zusammenführen wie folgt:

mytempdata = merge(mydata1, mydata2) 
mytempdata = merge(mytempdata, mydata3) 
. 
. 
. 
mytempdata = merge(mytempdata, mydata20) 

Das ist mühsam. Sie suchen vielleicht nach einem einfacheren Weg. Wenn Sie sind, habe ich eine Funktion, um Ihre Leiden zu lösen multmerge genannt() * Hier ist der Code ist die Funktion zu definieren.

multmerge = function(mypath){ 
filenames=list.files(path=mypath, full.names=TRUE) 
datalist = lapply(filenames, function(x){read.csv(file=x,header=T)}) 
Reduce(function(x,y) {merge(x,y)}, datalist) 

Hier ist eine gute Ressource, die Ihnen helfen sollen.

https://stats.idre.ucla.edu/r/codefragments/read_multiple/

Verwandte Themen