2016-05-20 11 views
1

Meine globale Umgebung enthält mehrere Datenrahmen. Ich möchte nur Funktionen ausführen, die eine bestimmte Zeichenfolge in ihrem Namen enthalten. Also, ich zum ersten Mal eine Liste dieses Datenrahmen von Interesse erstellen:in R: Funktion auf Datenrahmen ausführen, deren Namen in der Liste sind

dfs <- ls()[sapply(ls(), function(x) class(get(x))) == 'data.frame'] 
dfs <- as.data.frame(dfs) 
dfs_lst <- agrep("stats", dfs$dfs, ignore.case=FALSE, value=TRUE, 
    max.distance=0.1, useBytes=FALSE) 

dfs_lst korrekt gibt alle Datenrahmen in meiner globalen Umgebung mit der Zeichenfolge „Statistiken“. dfs_lst

chr [1:3] "stats1" "stats2" "stats3". 

Jetzt will ich Funktionen auf diesen drei Datenrahmen auszuführen, aber ich weiß nicht, wie sie von der dfs_lst nennen. Ich möchte etwas von der Art:

for(i in 1:length(dfs_lst){ 
    # Find dataframe name in dfs_lst, and then use the matching dataframe in 
    # global environment. So, something of the sort: 
    for(dfs_lst[i] in ls()){ 
     result[i,] <- dfs_lst[i] %>% 
           summarise(. , <summarise stuff>) 
    } 
} 

Zum Beispiel für i = 1, dfs_lst [1] ist Datenrahmen „stats1“, ich möchte das Folgende auszuführen, und es in der ersten Reihe „Ergebnisse speichern „:

for(stats1 in ls()){ 
     result[1,] <- stats1 %>% summarise(. , <summarise stuff>) 
    } 
+10

Sie sollten solche data.frames in einer Liste speichern. Dann hätten Sie solche Probleme nicht. Beispiele und Details finden Sie in der folgenden [post] (http://stackoverflow.com/questions/17499013/how-do-i-make-a-list-of-data-frames/24376207). Es wirkt auf den ersten Blick komisch, macht aber viele Operationen viel einfacher. – lmo

+4

Wenn Sie bereits die Namen Ihrer Zielobjekte haben, können Sie einfach so etwas wie 'lapply (mget (dfs [, 1], envir = .GlobalEnv), function (x) {...})' machen. – nrussell

+2

In einer Prise gibt es immer 'substitute (x, list (x = dfs_lst [1])' 'oder' eval (parse (text = dfs_lst [1])) ', aber sie in eine Liste zu setzen ist eine bessere Option, bevor Sie resort zu solchen Shenanigans. [Eine Art von verwandten lesen.] (http://adv-r.had.co.nz/Computing-on-the-language.html) – alistaire

Antwort

4

Wie @lmo wies darauf hin, ist es wahrscheinlich am besten, diese data.frame s in einem einzigen list zu speichern. Stattdessen data.frame Objekte mit dem Namen "stats1", "stats2", etc, im Umlauf in Ihrer Umgebung, eine (Hacky) Art und Weise alle in einem Ihrer data.frame Objekte zu speichern list ist dies:

dfs <- ls()[sapply(ls(), function(x) class(get(x))) == 'data.frame'] 

##make an empty list 
my_list <- list() 
##populate the list 
for (dfm_name in dfs) { 
    my_list[[dfm_name]] <- get(dfm_name) 
} 

jetzt haben Sie habe eine Liste my_list, die jedes Objekt der Klasse data.frame in Ihrer Umgebung enthält. Dies wird wahrscheinlich hilfreich sein, wenn Sie mit allen data.frame s Namen „statsX“ arbeiten wollen:

##find all list objects whose name starts with "stats" 
stats_objects <- substr(names(my_list),1,5)=="stats" 
results <- matrix(NA, ncol = your_length, nrow = sum(stats_objects)) 
##now perform intended operations 
for (row_num in 1:nrow(results)) { 
    results[i,] <- my_list[stats_objects][[row_num]] %>% 
          summarise(. , <summarise stuff>) 
} 

Dies sollte als notwendig, nach ein paar Änderungen im Code ausführen (zB your_length angegeben werden muss, und man wollte alle Objekte, deren Name "stats" enthält, so dass Sie mit regulären Ausdrücken arbeiten müssen.

Was schön ist, über diese my_list ist es, alle data.frames enthält, wenn Sie also data.frames nicht dem Namen „Statistik“ laufen Analyse wählen Sie können sie nach wie vor mit einem ähnlichen Verfahren zuzugreifen. Hoffe das hilft.

+0

Dies kann ein bisschen sauberer mit 'apropos' sein und 'mget'; etwas wie' lapply (Filter (is.data.frame, mget (apropos ("stats", mode = "liste"), .GlobalEnv)), function (x) {...}) '. – nrussell

1

Wie in den Kommentaren besprochen, wenn wir eine Liste von interessanten Datenrahmen haben, wird es einfacher sein, mit den Elementen als Datenrahmen umzugehen. Das Hauptproblem hier scheint also nur die Objektnamen und nicht die eigentlichen data.frame-Objekte zu haben.

Um den Code und die Verfolgung der Datentypen zu folgen, habe ich es zuerst zerlegt:

1.

env.list <- ls() # chr vector 

2.

env.classes <- sapply(env.list, function(x) class(get(x))) 
    # list of chr (containing classes), element names: data frame names 

3.

dfs <- env.list[env.classes == 'data.frame'] # chr vector 

4.

dfs <- as.data.frame(dfs) 
    # data frame with one column (named "dfs"), containing data.frame names 

Jetzt können wir die Liste der data.frames erhalten:

3.

dfs <- env.list[env.classes == 'data.frame'] # chr vector 
    dfs.list <- sapply(dfs, function(x) {get(x)}) 

grep können nun names(dfs.list) angewendet werden, um die interessanten Datenrahmen zu erhalten.