2016-08-18 11 views
0

Ich lerne, wie man R-Funktionen schreibt, die ein Verzeichnis voller Dateien lesen und die Anzahl der vollständig beobachteten Fälle in jeder Datei melden.For Loop zeigt nur den letzten Datensatz an

Meine Funktion arbeitet mit einem Fall, aber mit mehreren Fällen zeigt die Schleife nur den letzten Datensatz.

complete <- function(directory, id = 1:332) { 
    files_list <- list.files(path = directory, full.names = TRUE) 
    dat <- data.frame() 
    for (i in id) { 
      dat <- rbind(dat, read.csv(files_list[i])) 
      } 
    nobs <- sum(complete.cases(dat)) 
    id <- i 
    data.frame(id, nobs) 
} 

Mein erwartetes Ergebnis, wenn

> complete("specdata", 1:6) 

    ## id nobs 
    ## 1 1 932 
    ## 2 2 711 
    ## 3 3 475 
    ## 4 4 338 
    ## 5 5 586 
    ## 6 6 463 

Stattdessen laufen, wenn id = 1: 6, ein data.frame mit zehn Ergebnissen Rückkehr, gibt sie:

> complete("Specdata", 1:6) 


    id nobs 
1 6 3562 

ich den Verdacht, Problem ist, dass die Funktion die Werte jedes Mal ersetzt, wenn sie durchläuft. Ich habe SO und anderswo nach Hilfe mit "nur letzte Aufzeichnung" Probleme gesucht und kann keine Lösung aus diesen anderen Antworten herausfinden.

Vielen Dank im Voraus für jede Hilfe. Ich bin ganz neu bei R, da ich mir sicher bin, dass es offensichtlich ist.

+0

@ZheyuanLi: ah ja, verpasste die Daten innerhalb der rbind Anruf. Hoppla. –

+1

Bitte geben Sie Ihre ** erwartete Ausgabe ** (ala [reproduzierbare Beispiele] (http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example)). Ihr Code (wie @ZheyuanLi angegeben) ist vollkommen klar, da Sie explizit einen einzeiligen Datenframe zurückgeben. Wenn Sie 'dat' zurückgeben wollen, dann muss das in der letzten Zeile sein (oder in' return (...) '). – r2evans

+0

@ r2evans - Ich habe den ursprünglichen Post mit meiner erwarteten Ausgabe bearbeitet, entschuldige mich, falls das unklar war und danke für deine Hilfe. – john1607

Antwort

0

Ich hoffe, das sollte funktionieren!

complete <- function(directory, id = 1:332) { 
     files_list <- list.files(path = directory, full.names = TRUE) 
     dat <- data.frame() 
     tmp <- data.frame() 
       for (i in id) { 
         dat <- rbind(dat, read.csv(files_list[i])) 
         nobs <- sum(complete.cases(dat)) 
         id <- i 
         tmp <- rbind(tmp,data.frame(id,nobs)) 
       } 


     tmp 
} 

Details:

Es ist in erster Linie, weil Sie den Datenrahmen nach der for Schleife zurückkehren sind daher der jüngste Wert von i eingestellt ist und die sum von allem. Sie müssen rbind bei jeder Iteration von for und return der letzte Datenrahmen

+0

das hat funktioniert, vielen Dank. Ich sehe jetzt, wie Sie zwei data.frames dat und tmp verwendet haben, um das Schreiben der Schleife über sich selbst zu lösen. – john1607

+0

@ john1607 Es ist ein typisches Anfängerproblem. Keine Bange. Codiere weiter! – amrrs

0

Ja, es ist eine Menge los in Ihrem Code, die nicht klar ist. Insbesondere macht rbind keinen Sinn angesichts Ihrer Beschreibung, noch hat ID als Parameter in Ihrer Funktion. Je mehr idiomatisch Sie das tun, was Sie beschreiben, ist ungefähr so, wo das Sapply die Dateiliste durchläuft und die anonyme Funktion es einliest und die Anzahl der vollständigen Fälle zurückgibt.

files_list <- list.files(path = directory, full.names = TRUE) 
sapply(files_list, function(fi) sum(complete.cases(read.csv(fi)))) 
Verwandte Themen