Seite 1 von 1

erstellen eines vektors

Verfasst: Di Dez 25, 2018 6:42 pm
von bastiansteudel
Hallo,
ich habe folgendes Problem, was sicher für einige hier leicht zu lösen ist:

Ich benötige eine Variable die Namen von Gattungen enthält, und zwar genauso viele male wie die Gattung Arten hat. Ich habe aber nur eine Liste mit Namen und der Anzahl der Arten, also

A 7
B 3
C 2

Ich bräuchte sowas wie

Variable <- (A,A,A,A,A,A,A,B,B,B,C,C)

natürlich ist das ganze viel mehr, also über 4000 Arten in 300 Gattungen...also nicht einfach zu schreiben...

Vielen Dank für Hilfe!

Gruß
Bastian

Re: erstellen eines vektors

Verfasst: Di Dez 25, 2018 8:54 pm
von jogo
Hallo Bastian,

willkommen im Forum!
bastiansteudel hat geschrieben: Di Dez 25, 2018 6:42 pm Ich benötige eine Variable die Namen von Gattungen enthält, und zwar genauso viele male wie die Gattung Arten hat. Ich habe aber nur eine Liste mit Namen und der Anzahl der Arten, also

A 7
B 3
C 2

Ich bräuchte sowas wie

Variable <- (A,A,A,A,A,A,A,B,B,B,C,C)
Im Prinzip macht das rep():

Code: Alles auswählen

rep(c("A", "B", "C"), c(7, 3, 2))
Wenn Du uns jetzt noch konkrete Infos zu der Liste lieferst, dann kann die Antwort auch besser ausfallen.

Gruß, Jörg

Re: erstellen eines vektors

Verfasst: Mi Dez 26, 2018 8:48 am
von Hufeisen
Ich habe auch mal daran gebastelt :).

Code: Alles auswählen

# Testdaten erzeugen
forum <- data.frame(letters = letters[1:3], numbers = round(runif(3,1,10)), stringsAsFactors = FALSE)

> forum
  letters numbers
1       a       6
2       b       6
3       c      10

# Zielobjekt erstellen
vector1 <- vector(mode = "character")

# Zielobjekt füllen
for (i in 1:nrow(forum)) {
  
  vector1 <- c(vector1, 
               rep(forum[i,"letters"], forum[i,"numbers"]))
  
}

# Zielobjekt anzeigen
vector1
> vector1
 [1] "a" "a" "a" "a" "a" "a" "b" "b" "b" "b" "b" "b" "c" "c" "c" "c" "c"
[18] "c" "c" "c" "c" "c

Re: erstellen eines vektors

Verfasst: Mi Dez 26, 2018 11:20 am
von Athomas
Wenn man sich die Hilfe zu "rep" anguckt, sieht man, dass jogos vektorisierter Weg der natürliche - und wahrscheinlich ganz erheblich schnellere - ist...

Re: erstellen eines vektors

Verfasst: Mi Dez 26, 2018 11:20 am
von jogo
Hallo Hufeisen,

ohne for-Schleife geht es schneller!

Code: Alles auswählen

# Testdaten erzeugen
set.seed(42)
forum <- data.frame(letters = letters[1:3], numbers = round(runif(3,1,10)), stringsAsFactors = FALSE)
rep(forum$letters, forum$numbers)
... aber danke für das Bereitstellen der Testdaten - das hat der Fragende bisher versäumt.

Gruß, Jörg

Re: erstellen eines vektors

Verfasst: Mi Dez 26, 2018 12:09 pm
von Hufeisen
Schau an, das ist natürlich eine schöne, elegante Lösung.

Code: Alles auswählen

rep(forum[,"letters"], forum[,"numbers"])
Ich greife immer gerne zu Schleifen, weil die sich für mich gut lesen und nachvollziehen lassen - auch sprachenübergreifend. Bei der Lösung mit rep() müsste ich wohl erst in die Hilfe gucken oder mir Testdaten erzeugen, um sicher nachzuvollziehen, was da jetzt passiert. :oops: :D

Re: erstellen eines vektors

Verfasst: Mi Dez 26, 2018 1:33 pm
von jogo
Hufeisen hat geschrieben: Mi Dez 26, 2018 12:09 pm Schau an, das ist natürlich eine schöne, elegante Lösung.

Code: Alles auswählen

rep(forum[,"letters"], forum[,"numbers"])
diese Variante ist etwas sicherer und spart dem Interpreter noch ein µ an Arbeit.
Ich greife immer gerne zu Schleifen, weil die sich für mich gut lesen und nachvollziehen lassen - auch sprachenübergreifend.
klar, in fast jeder 3G-Programmiersprache ist die Schleife als Sprachkonstrukt vorhanden. Aber R ist eine 4G-Sprache - so dass man ihr Potential nur richtig nutzt, wenn man auch die passenden Konstrukte verwendet.
"Nutze die Macht!" - in diesem Fall die der Vektorisierung.

Gruß, Jörg

Re: erstellen eines vektors

Verfasst: Do Dez 27, 2018 1:17 am
von bastiansteudel
Vielen Dank für die umfangreiche und superschnelle Hilfe!

Es funktioniert hervorragend und auch meine Bedenken, dass es zu Problemen führen könnte, wenn eine Gattung nicht vorkommt, sprich die "Nummer" 0 ist, wurden zum Glück nicht erfüllt!

Re: erstellen eines vektors

Verfasst: Do Dez 27, 2018 12:27 pm
von EDi
Hufeisen hat geschrieben: Mi Dez 26, 2018 8:48 am Ich habe auch mal daran gebastelt :).

Code: Alles auswählen

# Testdaten erzeugen
forum <- data.frame(letters = letters[1:3], numbers = round(runif(3,1,10)), stringsAsFactors = FALSE)

> forum
  letters numbers
1       a       6
2       b       6
3       c      10

# Zielobjekt erstellen
vector1 <- vector(mode = "character")

# Zielobjekt füllen
for (i in 1:nrow(forum)) {
  
  vector1 <- c(vector1, 
               rep(forum[i,"letters"], forum[i,"numbers"]))
  
}

# Zielobjekt anzeigen
vector1
> vector1
 [1] "a" "a" "a" "a" "a" "a" "b" "b" "b" "b" "b" "b" "c" "c" "c" "c" "c"
[18] "c" "c" "c" "c" "c
Für kleine Daten kein Problem, für große ein Genickbruch, da sehr ineffizient. Hier wird vector1 mindestens 1x je Schleifendurchlauf kopiert (copy on modify) und das raubt zeit und speicher. Wie oft genau kopiert wird, kann man sich mit

Code: Alles auswählen

tracemem(vector1) 
anschauen. Mehr dazu hier https://adv-r.hadley.nz/names-values.ht ... -on-modify