2017-11-04 4 views
2

In meinem Datenrahmen habe ich eine Zeichenspalte. Ich möchte eine neue Spalte aus der vorhandenen Zeichenspalte mit einer Funktion erstellen, die ich selbst geschrieben habe.Neue Spalte mit Anwendungsfamilie erstellen

Meine Funktion

lat_finder <- function(coord){ 
return(as.numeric(substr(strsplit(coord,",")[[1]][1],2,10)))} 

Test-Datenrahmen

test <- data.frame('loc' = c("(37.7862913318072, -122.401375181471)","(37.7646938184545, -122.449439257453)","(37.7860078381928, -122.430650176965)")) 

ich dieses bin versucht

test['Lat'] <- lapply(test['loc'],lat_finder) 

Das Ergebnis ist eine neue Spalte, aber nur mit dem Ergebnis der Funktion von die erste Zeile, dh der erste Breitengrad, sollte 37.786 sein ... und dies ist der Wert für jede Zeile in der neuen Spalte. Ich weiß, dass eine For-Schleife funktionieren würde, da ich diese Operation schon einmal gemacht habe, aber es dauert eine ganze Weile, also würde ich das gerne beschleunigen. Ich bin mir sicher, es ist klar, dass ich hier etwas unter der Haube verpasse, also würde ich neben einer Fehlerbehebung auch eine Erklärung dafür, was mein Code macht, schätzen.

+0

Hinweis: Im ursprünglichen Beitrag habe ich den gesamten Datenrahmen, mit dem ich arbeitete, falsch referenziert. Es hätte laufen sollen (Test ['loc'] ....) und wurde korrigiert. – maxo

Antwort

0

Eine erste Notiz - weil Ihr Anruf data.frame ist stringsAsFactors = FALSCH Sie konvertieren Sie Ihre Eingabezeichenfolge als ein Faktor fehlt, die das Problem nicht wiederholbar, wie Sie es sagen, macht. Das sagte ich denke, dass vielleicht nur ein Problem in Ihrem Testcode sein und nicht die Wurzel des eigentlichen Problems, ich fügte hinzu, dass und gehen von dort aus:

test_f <- data.frame('loc' = c("(37.7862913318072, -122.401375181471)", 
          "(37.7646938184545, -122.449439257453)", 
          "(37.7860078381928, -122.430650176965)"), 
       stringsAsFactors = FALSE) 

Mit gesagt, dass die zugrunde liegende Problem ist die Art und Weise Sie ziehen die Spalte "loc". Dieser Platz-Klammern, zieht Stringauswahl eine einspaltige Datenrahmen:

> your_pull <- test_f['loc'] 
> your_pull 
            loc 
1 (37.7862913318072, -122.401375181471) 
2 (37.7646938184545, -122.449439257453) 
3 (37.7860078381928, -122.430650176965) 
> typeof(your_pull) 
[1] "list" 
> class(your_pull) 
[1] "data.frame" 

lapply wird ein Vektor als Eingabe erwartet, die Sie mit dem klassischen $ Notation bekommen:

> dollar_pull <- test_f$loc 
> dollar_pull 
[1] "(37.7862913318072, -122.401375181471)" "(37.7646938184545, -122.449439257453)" 
[3] "(37.7860078381928, -122.430650176965)" 
> typeof(dollar_pull) 
[1] "character" 
> class(dollar_pull) 
[1] "character" 

Der Funktionsaufruf funktioniert jetzt (erwarten Sie eine Liste bekommen, wo Sie einen Vektor wollen könnte - meine zufällige Hinweise siehe unten):

> lapply(test_f$loc,lat_finder) 
[[1]] 
[1] 37.78629 

[[2]] 
[1] 37.76469 

[[3]] 
[1] 37.78601 

ein paar incidenta ls:

1) wahrscheinlich eine gute Idee, die neue Spalte auch mit $ zuzuweisen.

2) Sie könnten Sapply oder Vapply verwenden, die einen Vektor anstatt einer Liste für Ihre neue data.frame-Spalte erzeugen wird.

3) Vielleicht möchten Sie die Anwendungsfamilie für Hadley Wickhams Schnurr-Paket aufgeben. Als Referenz wäre der Anruf hier purrr::map_chr(test_f$loc, you_function)

+0

Danke für die funktionale Hilfe und die gründliche Erklärung. – maxo

1

Ich bin nicht ganz sicher, was Ihr gewünschtes Ergebnis ist, aber ist das so nahe?

test <- data.frame(loc = c("(37.7862913318072, -122.401375181471)", 
          "(37.7646938184545, -122.449439257453)", 
          "(37.7860078381928, -122.430650176965)")) 
test$loc <- gsub("[\\(\\)]", "", test$loc) 
lonlat <- do.call(rbind, strsplit(test$loc,",")) 
lonlat <- matrix(as.numeric(lonlat), nrow(lonlat)) 
lonlat 

#   [,1]  [,2] 
# [1,] 37.78629 -122.4014 
# [2,] 37.76469 -122.4494 
# [3,] 37.78601 -122.4307 
+2

Sie sollten wahrscheinlich irgendwo 'as.numeric' hinzufügen, da Sie am Anfang jedes' X2' ein "Leerzeichen" verbergen. (Und ihre 'Faktor's.) – r2evans

+0

Wirklich schlaue Lösung. Ich war auch auf der Suche nach einer Erklärung der Familie apply, also musste ich alex.h die Antwort geben, aber ich werde diesen Trick auf jeden Fall behalten. – maxo

Verwandte Themen