2016-05-04 4 views
0

Wie vielleicht durch den Titel vorgeschlagen, ist diese Frage ein Follow-up zu diesem ähnlich betitelten question. Dort fragte ich, wie man eine Zeichenspalte eines Datenrahmens in mehrere numerische Spalten unter Verwendung des Trennzeichens _ aufteilt und Ergebnisse bereinigt. In diesem Fall waren alle Spalten numerisch und sie wurden aus den folgenden Elementen der geteilten Spalten erstellt, sodass die Lösung einfacher war. Dieses Mal sind die Dinge ein wenig anders:Erstellen Sie mehrere Spalten * in einem anderen Format * aus einer einzelnen Spalte und bereinigen Sie die Ergebnisse

foo <- data.frame(Point.Type = c("Zero Start","Zero Start", "Zero Start", "3000rpm_10%_13barG_Sdsdsa_1.0_F_Pww","3000rpm_10%_13barG_Sdsdsa_1.0_F_Pww","3000rpm_10%_13barG_Sdsdsa_1.0_R_Pww","Zero Stop","Zero Start"), 
       Point.Value = c(NA,NA,NA,rnorm(3),NA,NA)) 

Von Spalte Point.Type, ich brauche vier Spalten zu erstellen, rpm, GVF, p0 und Setup.

  • rpm, GVF, p0 müssen vom Typ numeric oder integer sein, während Setup vom Typ character sein muss.
  • Alle vier neuen Spalten müssen auf NA gesetzt werden, wenn Point.Type keine _ enthält (Zeilen 1,2,3,7,8 in meinem Beispiel).
  • wenn Point.Type ein _ enthält, dann rpm, GVF, p0 muß die ersten drei Elemente von Point.Type enthalten, „gereinigt“ von allen nicht numerischen Zeichen. Setup muss gleich Full sein, wenn das 6. Element von Point.Type gleich F ist, andernfalls muss es gleich Reduced sein. In meinem Beispiel bedeutet dies, dass Setup sollte Full für die Zeilen 4 und 5 zu Reduced für Zeile 6.

Um die drei numeric Spalten gleich sein, verwende ich die ausgezeichnete Lösung von @Procrastinatus_Maximus, hier etwas umformuliert :

library(dplyr) 
foo <- foo %>% 
    separate(Point.Type, c("rpm", "GVF", "p0"), 
      sep="_", remove = FALSE, extra="drop", fill="right") %>% 
    mutate_each(funs(as.numeric(gsub("[^0-9]","",.))), rpm, GVF, p0) 

Nun ist das Problem der character Spalte, Setup. Schreiben Sie einfach naiv

library(dplyr) 
foo <- foo %>% 
    separate(Point.Type, c("rpm", "GVF", "p0","Setup"), 
      sep="_", remove = FALSE, extra="drop", fill="right") %>% 
    mutate_each(funs(as.numeric(gsub("[^0-9]","",.))), rpm, GVF, p0,Setup) 

wird nicht funktionieren, weil der Wert von Setup nicht auf das Element von Point.Type unmittelbar nach p0 zusammenhängt. Der Wert von Setup hängt auch davon ab, ob das sechste Element Point.TypeF oder R ist, aber dies sind character Werte und sie werden einfach von mutate_each(funs(as.numeric(gsub("[^0-9]","",.))),... weggefegt. Ich habe irgendwo mit diesem Code:

library(dplyr) 
foo <- foo %>% 
    separate(Point.Type, c("rpm", "GVF", "p0"), 
      sep="_", remove = FALSE, extra="drop", fill="right") %>% 
    mutate_each(funs(as.numeric(gsub("[^0-9]","",.))), rpm, GVF, p0) 
library(stringr) 
foo$Setup <- ifelse(str_split_fixed(setup$Point.Type,"_",7)[,6]=="F", 
           "Full","Reduced") 

, die mir jedoch

      Point.Type rpm GVF p0 Point.Value Setup 
1       Zero Start NA NA NA   NA Reduced 
2       Zero Start NA NA NA   NA Reduced 
3       Zero Start NA NA NA   NA Reduced 
4 3000rpm_10%_13barG_Sdsdsa_1.0_F_Pww 3000 10 13 1.9188554 Full 
5 3000rpm_10%_13barG_Sdsdsa_1.0_F_Pww 3000 10 13 -0.5743683 Full 
6 3000rpm_10%_13barG_Sdsdsa_1.0_R_Pww 3000 10 13 -0.7122796 Reduced 
7       Zero Stop NA NA NA   NA Reduced 
8       Zero Start NA NA NA   NA Reduced 

gibt, wie Sie es noch nicht sehen können nicht funktionieren: Setup gleich Reduced auch in jenen Fällen, wo es sein sollte gleich NA. Auch, ehrlich gesagt mag ich nicht die Idee, stringr zu laden, nur um Setup zu erstellen. Ich würde viel lieber den ganzen Job in dplyr machen, vorzugsweise in einer einzigen Codezeile mit Pipes. Wenn das zu unlesbarem Code führt, wären zwei aufeinanderfolgende Aufrufe an dplyr ebenfalls in Ordnung.

+0

Ich sehe nicht wirklich, wie diese Frage "zu breit" wäre, während die vorhergehende (von der dies nur eine hoffentlich einfache Erweiterung ist) nicht allzu breit war. Warum würde es zu weit gefasst sein, nur eine weitere Spalte zu verwalten? – DeltaIV

Antwort

2

Hier ist mein Versuch. Ich denke, das, wonach du fragst. Ich nahm das letzte Beispiel und fügte am Ende der Kette ein muate hinzu.

library(dplyr) 
library(tidyr) 

foo <- data.frame(Point.Type = c("Zero Start","Zero Start", "Zero Start", "3000rpm_10%_13barG_Sdsdsa_1.0_F_Pww","3000rpm_10%_13barG_Sdsdsa_1.0_F_Pww","3000rpm_10%_13barG_Sdsdsa_1.0_R_Pww","Zero Stop","Zero Start"), 
        Point.Value = c(NA,NA,NA,rnorm(3),NA,NA)) 

res <- foo %>% 
    separate(Point.Type, c("rpm", "GVF", "p0"), 
      sep="_", remove = FALSE, extra="drop", fill="right") %>% 
    mutate_each(funs(as.numeric(gsub("[^0-9]","",.))), rpm, GVF, p0) %>% 
    mutate(Setup = ifelse(!is.na(rpm), ifelse(grepl("_F_", Point.Type),"Full", "Reduced"),NA)) 
+1

Es funktioniert! Ich verstehe nicht, warum die 'NA' im' Setup' anders aussehen als in den anderen drei Spalten (R druckt sie als '' anstelle von 'NA'). R scheint jedoch gut damit umzugehen, also ist das in Ordnung für mich. – DeltaIV

+1

@DeltaIV Der Grund, warum es als angezeigt wird, ist, es von einem Zeicheneintrag zu unterscheiden, der NA ist, wie die Abkürzung für Nordamerika. In einem einzelnen Vektor wird der Text in Anführungszeichen gesetzt, in einem Datenrahmen wird er nicht in Anführungszeichen gesetzt, also erhalten die NA < > um sie herum. – AllanT

+0

Ok, also, die 'NA' in den' numerischen' Spalten ('rpm',' GVF', 'p0') bekommen nicht das <> weil sie numerisch sind, also gibt es keine Verwechslung mit der Zeichenkette' "NA "'. In der 'Setup'-Spalte, die' character' ist, fügt R <> hinzu, um sie von der Zeichenkette zu unterscheiden. Verstanden. Vielen Dank! – DeltaIV

Verwandte Themen