Seite 1 von 1

Datensätze mit For loop erstellen

Verfasst: Do Jun 25, 2020 2:29 pm
von LeaRn
Hallo
Ich frage mich, ob man mehrere Datensätze mit einem For-loop (oder jeden anderen Technik) erstellen kann?

Unten sind 5 Beispiel-Datensätze aufgezeigt. Es geht darum, jede erdenkliche Kombination von 0 und 1 (ferner auch allen Zahlen zwischen 0 und 5) in einem eigenen Datensatz darzustellen (512 Datensätze).

Code: Alles auswählen

bsp1 <- data.frame(x = c(0, 0, 0),
                   y = c(0, 0, 0),
                   z = c(0, 0, 0))

bsp2 <- data.frame(x = c(0, 0, 0),
                   y = c(0, 0, 0),
                   z = c(1, 0, 0))

bsp3 <- data.frame(x = c(0, 0, 0),
                   y = c(1, 0, 0),
                   z = c(1, 0, 0))

bsp4 <- data.frame(x = c(1, 0, 0),
                   y = c(1, 0, 0),
                   z = c(1, 0, 0))    

bsp5 <- data.frame(x = c(1, 0, 0),
                   y = c(1, 0, 0),
                   z = c(0, 0, 0))                             		
Hat jemand eine Idee? Gibt es eine Möglichkeit, sowas mit wenig Code zu erreichen?
Einige Gedankenanstösse würden schon reichen, den Code dazu kann ich mir dann selber zusammenbasteln.

Re: Datensätze mit For loop erstellen

Verfasst: Do Jun 25, 2020 2:37 pm
von bigben
Ein wesentlicher Gedankenanstoß könnte dieser sein:

Code: Alles auswählen

> expand.grid(0:1, 0:1, 0:1)
  Var1 Var2 Var3
1    0    0    0
2    1    0    0
3    0    1    0
4    1    1    0
5    0    0    1
6    1    0    1
7    0    1    1
8    1    1    1
auch

Code: Alles auswählen

head(expand.grid(0:1, 0:1, 0:1, 0:1),15)
head(expand.grid(1:5, 1:5),15)
angenehm verkürzte Schreibweise (wenig Code) mit dem magrittr package:

Code: Alles auswählen

library(magrittr)
0:1 %>% expand.grid(.,.,.,.)
1:5 %>% expand.grid(.,.)
LG,
Bernhard

Re: Datensätze mit For loop erstellen

Verfasst: Do Jun 25, 2020 3:21 pm
von bigben
Nachtrag. So, jetzt habe ich wenig Code, von dem ich glaube, dass er das produziert, was Du mit dem Beispiel oben gemeint hast:

Code: Alles auswählen

library(magrittr); 0:1 %>% expand.grid(.,.,.,.,.,.,.,.,.) %>%  t %>% data.frame %>%
lapply(function(ß) data.frame(matrix(ß, nrow=3), row.names = c("x", "y", "z")) %>% t) -> bsp
Nach diesem Zweizeiler heißen die dataframe nicht bsp1, bsp2, bsp3 sondern bsp[1], bsp[2] etc. Damit kann man sie dann auch viel leichter weiterverarbeiten. Probiere

Code: Alles auswählen

bsp[1]
bsp[9]
bsp[100]
bsp[511]
Viel Spaß damit,
Bernhard

Re: Datensätze mit For loop erstellen

Verfasst: Do Jun 25, 2020 3:48 pm
von LeaRn
Danke für die Antwort. Das ist genau was ich gesucht habe.

Ich habe es auch versucht, habe aber sehr umständlichen Code geschrieben. Hier meine Lösung:

Code: Alles auswählen

library(tidyverse)

 for (i in 1:8) {
    for (j in 1:8) {
      for (k in 1:8) {
        fr <- expand.grid(0:1, 0:1, 0:1)
        xa <- fr[i,]
        xb <- fr[j,]
        xc <- fr[k,]
        ax <- gather(xa, "Var")
        bx <- gather(xb, "Var")
        cx <- gather(xc, "Var")
        result <- left_join(ax, bx, by='Var') %>% left_join(., cx, by='Var') %>% select(-Var)
        print(result)
      }
    }
  }


Ich habe es aber nicht geschafft, die Datensätze jeweils einzeln abzuspeichern.

Beste Grüsse
LeaRn

Re: Datensätze mit For loop erstellen

Verfasst: Do Jun 25, 2020 4:23 pm
von bigben
Ich greife mal Deine Idee auf, die möglichen 3er-Konstellationen in fr zu speichern und dann mit drei geschachtelten for-Schleifen zu arbeiten. Dafür braucht man expand.grid aber nicht jedes Mal in der innersten Schleife aufzurufen, sondern nur ein einziges Mal am Anfang. Den ganzen tidyverse-Kram den Du da einbauen wolltest habe ich nicht unterbekommen. Es gibt andere im Forum, die das besser können.

Code: Alles auswählen

result <-  list(1, 2, 3)
l <-1

fr <- expand.grid(0:1, 0:1, 0:1)
for (i in 1:8) {
  for (j in 1:8) {
    for (k in 1:8) {
      result[[l]] <- as.data.frame(rbind(fr[i,], fr[j,], fr[k,]))
      l <- l + 1
    }
  }
}[

result/code]

Wenn man das dann im nächsten Schritt nicht mit den Zahlen 0:1 sondern 1:5 macht, werden die Rechenanforderungen und die Wartezeiten schnell anwachsen. Dann könnte es interessant werden, die äußerste der drei Schleifen durch eine foreach-Schleife zu ersetzen und die Rechenarbeit so auf 5 Rechenkerne zu verteilen, ohne den Rest des Codes groß umschreiben zu müssen. 
Mit meinem "Zweizeiler" von oben geht das nicht, solange nicht jemand ein parallelisiertes expand.grid schreibt.

LG,
Bernhard