2013-07-11 16 views
6

Ich arbeite in R und habe einen Datenrahmen, dd_2006, mit numerischen Vektoren. Als ich die Daten zum ersten Mal importierte, musste ich $, Dezimalpunkte und einige Leerzeichen aus 3 meiner Variablen entfernen: SumOfCost, SumOfCases und SumOfUnits. Um das zu tun, habe ich str_replace_all verwendet. Sobald ich jedoch str_replace_all verwendet habe, wurden die Vektoren in Zeichen konvertiert. Also habe ich as.numeric (var) verwendet, um die Vektoren in numerische umzuwandeln, aber NAs wurden eingeführt, obwohl, wenn ich den Code unten ausführte, BEVOR ich den as.numerischen Code ausführte, gab es keine NAs in den Vektoren.Umwandlung von Zeichen in Numerisch ohne NA-Koerzition in R

sum(is.na(dd_2006$SumOfCost)) 
[1] 0 
sum(is.na(dd_2006$SumOfCases)) 
[1] 0 
sum(is.na(dd_2006$SumOfUnits)) 
[1] 0 

Hier ist mein Code von nach dem Import, beginnend mit dem Entfernen der $ aus dem Vektor. In der str(dd_2006) Ausgabe löschte ich einige der Variablen aus Platzgründen, so dass die Spalte #s in der str_replace_all Code unten nicht die Ausgabe, die ich hier gepostet habe (aber sie tun im ursprünglichen Code):

library("stringr") 
dd_2006$SumOfCost <- str_sub(dd_2006$SumOfCost, 2,) #2=the first # after the $ 

#Removes decimal pt, zero's after, and commas 
dd_2006[ ,9] <- str_replace_all(dd_2006[ ,9], ".00", "") 
dd_2006[,9] <- str_replace_all(dd_2006[,9], ",", "") 

dd_2006[ ,10] <- str_replace_all(dd_2006[ ,10], ".00", "") 
dd_2006[ ,10] <- str_replace_all(dd_2006[,10], ",", "") 

dd_2006[ ,11] <- str_replace_all(dd_2006[ ,11], ".00", "") 
dd_2006[,11] <- str_replace_all(dd_2006[,11], ",", "") 

str(dd_2006) 
'data.frame': 12604 obs. of 14 variables: 
$ CMHSP      : Factor w/ 46 levels "Allegan","AuSable Valley",..: 1 1 1 
$ FY      : Factor w/ 1 level "2006": 1 1 1 1 1 1 1 1 1 1 ... 
$ Population    : Factor w/ 1 level "DD": 1 1 1 1 1 1 1 1 1 1 ... 
$ SumOfCases    : chr "0" "1" "0" "0" ... 
$ SumOfUnits    : chr "0" "365" "0" "0" ... 
$ SumOfCost     : chr "0" "96416" "0" "0" ... 

fand ich eine Antwort auf eine ähnliche Frage here verminen, mit dem folgenden Code:

# create dummy data.frame 
d <- data.frame(char = letters[1:5], 
       fake_char = as.character(1:5), 
       fac = factor(1:5), 
       char_fac = factor(letters[1:5]), 
       num = 1:5, stringsAsFactors = FALSE) 

Lassen Sie uns einen Blick data.frame haben

> d 
    char fake_char fac char_fac num 
1 a   1 1  a 1 
2 b   2 2  b 2 
3 c   3 3  c 3 
4 d   4 4  d 4 
5 e   5 5  e 5 

und lassen Sie uns laufen:

> sapply(d, mode) 
     char fake_char   fac char_fac   num 
"character" "character" "numeric" "numeric" "numeric" 
> sapply(d, class) 
     char fake_char   fac char_fac   num 
"character" "character" "factor" "factor" "integer" 

Jetzt haben Sie wahrscheinlich fragen Sie sich: „Wo ist eine Anomalie?“ Nun, ich bin in R ganz besondere Dinge angegangen, und das ist nicht das Verwirrendste, aber es kann Sie verwirren, besonders wenn Sie dies lesen, bevor Sie ins Bett rollen.

Hier geht: erste zwei Spalten sind Zeichen. Ich habe absichtlich den 2. einen fake_char genannt. Finde die Ähnlichkeit dieser Zeichenvariablen mit einer, die Dirk in seiner Antwort erstellt hat. Es ist eigentlich ein numerischer Vektor, der in Zeichen umgewandelt wurde. Die dritte und vierte Spalte sind Faktoren, und die letzte ist "rein" numerisch.

Wenn Sie die Transformationsfunktion verwenden, können Sie den Wert von fake_char in numerisch, aber nicht in die Variable char konvertieren.

> transform(d, char = as.numeric(char)) 
    char fake_char fac char_fac num 
1 NA   1 1  a 1 
2 NA   2 2  b 2 
3 NA   3 3  c 3 
4 NA   4 4  d 4 
5 NA   5 5  e 5 
Warning message: 
In eval(expr, envir, enclos) : NAs introduced by coercion 
but if you do same thing on fake_char and char_fac, you'll be lucky, and get away with no NA's: 

Transformations (d, fake_char = as.numeric (fake_char), char_fac = as.numeric (char_fac))

char fake_char fac char_fac num 
1 a   1 1  1 1 
2 b   2 2  2 2 
3 c   3 3  3 3 
4 d   4 4  4 4 
5 e   5 5  5 5 

Also versuchte ich den obigen Code in meinem Skript , kam aber immer noch mit NAs (ohne eine Warnmeldung über Zwang).

#changing sumofcases, cost, and units to numeric 
dd_2006_1 <- transform(dd_2006, SumOfCases = as.numeric(SumOfCases), SumOfUnits = as.numeric(SumOfUnits), SumOfCost = as.numeric(SumOfCost)) 

> sum(is.na(dd_2006_1$SumOfCost)) 
[1] 12 
> sum(is.na(dd_2006_1$SumOfCases)) 
[1] 7 
> sum(is.na(dd_2006_1$SumOfUnits)) 
[1] 11 

Ich habe auch verwendet table(dd_2006$SumOfCases) usw. zu den Beobachtungen, um zu sehen, ob es irgendwelche Zeichen, die ich in den Beobachtungen übersehen, aber es gab keine. Irgendwelche Gedanken darüber, warum die NAs auftauchen und wie man sie los wird?

+2

Sorry, aber was ist die Frage? Die verknüpfte Antwort scheint alles gut zu summieren, und ohne ein reproduzierbares Beispiel für das Problem, * Sie * sind tatsächlich konfrontiert, ich bin mir nicht sicher, wie andere helfen können .... – A5C1D2H2I1M1N2O1R2T1

+0

Ich vermute, diese Daten kamen aus Excel oder eine andere Tabelle. Nächstes Mal löschen Sie vor dem Export alle Formatierungen. –

Antwort

10

Wie Anando darauf hingewiesen hat, liegt das Problem irgendwo in Ihren Daten, und ohne ein reproduzierbares Beispiel können wir Ihnen nicht wirklich helfen.Das heißt, hier ist ein Code-Snippet Ihnen zu helfen, die Datensätze in Ihrer Daten festzunageln, dass Sie Probleme verursachen:

test = as.character(c(1,2,3,4,'M')) 
v = as.numeric(test) # NAs intorduced by coercion 
ix.na = is.na(v) 
which(ix.na) # row index of our problem = 5 
test[ix.na] # shows the problematic record, "M" 

Anstatt zu raten, warum NAs eingeführt werden, die Datensätze herausziehen, die das Problem verursachen und adressiere sie direkt/einzeln, bis die NAs verschwinden.

UPDATE: Sieht aus wie das Problem in Ihrem Anruf an str_replace_all ist. Ich weiß nicht, die stringr Bibliothek, aber ich glaube, Sie die gleiche Sache mit gsub wie dies erreicht werden kann:

v2 = c("1.00","2.00","3.00") 
gsub("\\.00", "", v2) 

[1] "1" "2" "3" 

Ich bin nicht ganz sicher, was erreicht dies aber:

sum(as.numeric(v2)!=as.numeric(gsub("\\.00", "", v2))) # Illustrate that vectors are equivalent. 

[1] 0 

Es sei denn, diese erreicht einen bestimmten Zweck für Sie, ich würde vorschlagen, diesen Schritt von Ihrer Vorverarbeitung vollständig fallen zu lassen, da es nicht notwendig scheint und Ihnen Probleme gibt.

+0

Wenn ich diesen Code für SumOfUnits ausführen, bekomme ich '> die (ix.na) #row Index des Problems NAs [1] 1098 2297 4728 5559 5592 5702 6955 8191 10517 10881 10955 > test [ix.na] # [ 1) "" "" "" "" "" "" "" ' Aber wenn ich diese Zeilen im ursprünglichen Dataset ansehe, sieht es so aus: ' SumOfUnits 800.00 0,00 100,00 100,00 100,00 300,00 400,00 200,00 200,00 600,00 100.00' wie ist, dass ein Profi blem mit den Daten statt etwas passiert, wenn ich den 'str_replace_all' Code ausführen? – idemanalyst

+0

Sieht aus wie Sie das Problem festgesteckt haben. Ich weiß nicht wirklich, was die Vorverarbeitung dieser Zeichenfolgen bewirkt, da Sie diese Werte mit oder ohne Dezimalstellen in Zahlen umwandeln können, aber ich illustriere eine alternative Lösung mit 'gsub' in meiner aktualisierten Antwort. –

+0

das ist es, danke! – idemanalyst

4

Wenn Sie das Zeichen auch in eine Zahl umwandeln möchten, konvertieren Sie es zuerst in einen Faktor (mit as.factor) und speichern/überschreiben Sie die vorhandene Variable. Als nächstes wandeln Sie diese Faktorvariable in numerisch um (mit as.numeric). Sie würden auf diese Weise keine NAs erstellen und können den Datensatz, den Sie haben, in numerische konvertieren.

+0

as.numeric (as.factor (df $ x)) ersetzt nur die Werte durch Indizes 1 und 2 –