Frage

Ich kann dies mit Schleifen lösen, aber ich versuche, denkt in Vektoren so mein Code mehr R-esque sein wird.

ich eine Liste von Namen haben. Das Format ist firstname_lastname. Ich möchte eine separate Liste von dieser Liste, um aus nur mit den Vornamen. Ich kann meine Gedanken nicht zu umgehen scheinen, wie dies zu tun. Hier einige Beispieldaten:

t <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
tsplit <- strsplit(t,"_")

, die wie folgt aussehen:

> tsplit
[[1]]
[1] "bob"   "smith"

[[2]]
[1] "mary" "jane"

[[3]]
[1] "jose"  "chung"

[[4]]
[1] "michael" "marx"   

[[5]]
[1] "charlie" "ivan"   

Ich konnte raus, was ich will mit Schleifen wie folgt aus:

for (i in 1:length(tsplit)){
    if (i==1) {t_out <- tsplit[[i]][1]} else{t_out <- append(t_out, tsplit[[i]][1])} 
}

, die geben würde mir diese:

t_out
[1] "bob"     "mary"    "jose"    "michael" "charlie"

Wie kann ich dies tun, ohne Schleifen?

War es hilfreich?

Lösung

Sie können mit apply (oder sapply)

t <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
f <- function(s) strsplit(s, "_")[[1]][1]
sapply(t, f)

bob_smith    mary_jane   jose_chung michael_marx charlie_ivan 

       "bob"       "mary"       "jose"    "michael"    "charlie" 

Siehe auch: Eine kurze Einführung in R

„Übernehmen“

Andere Tipps

Und noch ein Ansatz:

t <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
pieces <- strsplit(t,"_")
sapply(pieces, "[", 1)

In Worten, die letzte Zeile extrahiert das erste Element jeder Komponente der Liste und dann vereinfacht es in einen Vektor.

Wie funktionierts? Nun, Sie müssen eine alternative Art und Weise realisieren x[1] des Schreibens ist "["(x, 1), das heißt, es ist eine Funktion namens [, die nicht subsetting. Der sapply Aufruf gilt Anrufe diese Funktion einmal für jedes Element der ursprünglichen Liste, in zwei Argumenten zu übergeben, das Listenelement und 1.

Der Vorteil dieses Ansatzes gegenüber den anderen ist, dass Sie, ohne dass mehrere Elemente aus der Liste zu extrahieren, der die Spalten neu zu berechnen. Zum Beispiel würde der letzte Name sapply(pieces, "[", 2) werden. Sobald Sie in dieses Idiom zu gewöhnen, ist es ziemlich einfach zu lesen.

Wie wäre:

tlist <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
fnames <- gsub("(_.*)$", "", tlist)
# _.* matches the underscore followed by a string of characters
# the $ anchors the search at the end of the input string
# so, underscore followed by a string of characters followed by the end of the input string

für den RegEx Ansatz?

was ist:

t <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")

sub("_.*", "", t)

Ich bezweifle, dass dies die eleganteste Lösung, aber es schlägt Looping:

t.df <- data.frame(tsplit)
t.df[1, ]

Listen Datenrahmen Konvertieren ist über die einzige Art, wie ich sie bekommen kann zu tun, was ich will. Ich freue mich auf Antworten von Menschen zu lesen, die tatsächlich verstehen, wie Listen zu handhaben.

Sie fast hatte. Es wirklich ist nur eine Frage der

  1. Mithilfe der *apply Funktionen in einer Schleife über die bestehende Liste, beginne ich oft mit lapply und manchmal wechseln sapply
  2. fügen Sie eine anonyme Funktion, die zu einer Zeit auf einem der Listenelemente arbeitet
  3. Sie bereits wusste, es war strsplit(string, splitterm) und dass Sie die ungerade [[1]][1] brauchen die erste Laufzeit der Antwort
  4. pflücken
  5. es nur alle zusammen mit einem bevorzugten variablen namne beginnen (wie wir klar von t oder c und Freunden zu bleiben)

das gibt

> tlist <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan") 
> fnames <- sapply(tlist, function(x) strsplit(x, "_")[[1]][1]) 
> fnames 
  bob_smith    mary_jane   jose_chung michael_marx charlie_ivan   
      "bob"       "mary"       "jose"    "michael"    "charlie" 
>

Sie könnten unlist() verwenden:

> tsplit <- unlist(strsplit(t,"_"))
> tsplit
 [1] "bob"     "smith"   "mary"    "jane"    "jose"    "chung"   "michael"
 [8] "marx"    "charlie" "ivan"   
> t_out <- tsplit[seq(1, length(tsplit), by = 2)]
> t_out
[1] "bob"     "mary"    "jose"    "michael" "charlie"

Es könnte eine bessere Art und Weise sein, nur die ungeraden indizierte Einträge zu ziehen, aber in jedem Fall, dass Sie nicht eine Schleife haben.

Und ein anderer Ansatz, der auf brentonk des fehlenden oder Beispiel ...

tlist <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
tsplit <- unlist(strsplit(tlist,"_"))
fnames <- tsplit[seq(1:length(tsplit))%%2 == 1]

Ich würde verwenden Sie die folgende fehlenden oder () - Methode auf Basis:

> t <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
> tsplit <- strsplit(t,"_")
> 
> x <- matrix(unlist(tsplit), 2)
> x[1,]
[1] "bob"     "mary"    "jose"    "michael" "charlie"

Der große Vorteil dieser Methode ist, dass es das Äquivalent Problem für Nachnamen, die gleichzeitig löst:

> x[2,]
[1] "smith" "jane"  "chung" "marx"  "ivan" 

Der Nachteil ist, dass Sie sicher sein müssen, werden feststellen, dass alle Namen auf die firstname_lastname Struktur entsprechen; wenn überhaupt nicht, dann wird diese Methode brechen.

aus dem ursprünglichen Objekt tsplit Liste am Anfang gegeben, wird dieser Befehl tun:

unlist(lapply(tsplit,function(x) x[1]))

es extrahiert das erste Element aller Listenelemente, wandelt dann eine Liste mit einem Vektor. Entadressierung zunächst auf eine Matrix, dann die Faust Säule Extraktion ist auch in Ordnung, aber dann sind Sie auf der Tatsache abhängig, dass alle Listenelemente die gleiche Länge haben. Hier ist die Ausgabe:

> tsplit

[[1]]
[1] "bob"   "smith"

[[2]]
[1] "mary" "jane"

[[3]]
[1] "jose"  "chung"

[[4]]
[1] "michael" "marx"   

[[5]]
[1] "charlie" "ivan"   

> lapply(tsplit,function(x) x[1])

[[1]]
[1] "bob"

[[2]]
[1] "mary"

[[3]]
[1] "jose"

[[4]]
[1] "michael"

[[5]]
[1] "charlie"

> unlist(lapply(tsplit,function(x) x[1]))

[1] "bob"     "mary"    "jose"    "michael" "charlie"
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top