Unseen Faktorstufen, wenn neue Datensätze mit unsichtbarem String-Wert zu einem Datenrahmen anhängt, verursachen Warnung und führen in NA

StackOverflow https://stackoverflow.com/questions/1632772

  •  06-07-2019
  •  | 
  •  

Frage

Ich habe einen Datenrahmen (14.5K Reihen von 15 Spalten) Abrechnungsdaten von 2001 bis 2007 enthält.

I anhängen neue Daten von 2008 an mit: alltime <- rbind(alltime,all2008)

Leider, dass eine Warnung aus:

> Warning message:
In `[<-.factor`(`*tmp*`, ri, value = c(NA, NA, NA, NA, NA, NA, NA,  :
  invalid factor level, NAs generated

Meine Vermutung ist, dass es einige neuen Patienten, deren Namen waren nicht in dem vorherigen Datenrahmen und daher wäre es nicht wissen, welche Ebene diejenigen zu geben. Ähnlich neue unsichtbare Namen in der Spalte ‚Zuweiser‘.

Was ist die Lösung?

War es hilfreich?

Lösung

Es könnte durch Mismatch von Typen in zwei data.frames verursacht werden.

Prüfen Sie zuerst Typen (Klassen). Zu Diagnosezwecken dies zu tun:

new2old <- rbind( alltime, all2008 ) # this gives you a warning
old2new <- rbind( all2008, alltime ) # this should be without warning

cbind(
    alltime = sapply( alltime, class),
    all2008 = sapply( all2008, class),
    new2old = sapply( new2old, class),
    old2new = sapply( old2new, class)
)

Ich erwarte, dass es seine eine Reihe wie folgt aussieht:

            alltime  all2008   new2old  old2new
...         ...      ...       ...      ...
some_column "factor" "numeric" "factor" "character"
...         ...      ...       ...      ...

Wenn ja, dann Erklärung: rbind nicht Arten Spiel überprüfen. Wenn Sie rbind.data.frame Code analysieren dann konnte man sehen, dass das erste Argument Ausgabetypen initialisiert. Wenn in dem ersten data.frame Typ ein Faktor ist, dann Ausgang data.frame Spalt Faktor mit Ebenen unique(c(levels(x1),levels(x2))). Aber wenn in der zweiten data.frame Spalte nicht ist Faktor dann ist levels(x2) NULL, so Ebenen erstrecken sich nicht.

Es bedeutet, dass Ihre Ausgangsdaten falsch sind! Es gibt NA ist statt der wahren Werte

Ich nehme an, dass:

  1. Sie erstellen Sie alte Daten mit einem anderen R / RODBC Version so Typen mit unterschiedlichen Methoden (verschiedene Einstellungen - Dezimaltrennzeichens vielleicht) erstellt wurden
  2. gibt es NULL ist oder einige spezifische Daten in problematischen Spalte, zum Beispiel. jemand Spalte unter Datenbank ändern.

Lösung:

falsche Spalte finden und Grund finden, warum die falsch ist und fixiert. Ursache beseitigt nicht die Symptome.

Andere Tipps

Ein „easy“ Weg ist, einfach nicht haben Ihre Strings als Faktoren festgelegt, wenn Textdaten importieren.

Beachten Sie, dass die read.{table,csv,...} Funktionen einen stringsAsFactors Parameter nehmen, die standardmäßig auf TRUE gesetzt ist. Sie können dies auf FALSE während Sie importieren und rbind-ing Ihre Daten.

Wenn Sie möchten, dass die Spalte setzen einen Faktor am Ende zu sein, können Sie das auch tun.

Zum Beispiel:

alltime <- read.table("alltime.txt", stringsAsFactors=FALSE)
all2008 <- read.table("all2008.txt", stringsAsFactors=FALSE)
alltime <- rbind(alltime, all2008)
# If you want the doctor column to be a factor, make it so:
alltime$doctor <- as.factor(alltime$doctor)

1) schaffen den Datenrahmen mit stringsAsFactor auf FALSCH gesetzt. Dies sollte das Faktor-Problem beheben

2) danach nicht verwenden rbind - es vermasselt die Spaltennamen, wenn der Datenrahmen leer. einfach tut es so aus:

df[nrow(df)+1,] <- c("d","gsgsgd",4)

/

> df <- data.frame(a = character(0), b=character(0), c=numeric(0))

> df[nrow(df)+1,] <- c("d","gsgsgd",4)

Warnmeldungen:
1: In `[<-.factor`(`*tmp*`, iseq, value = "d") :
  invalid factor level, NAs generated
2: In `[<-.factor`(`*tmp*`, iseq, value = "gsgsgd") :
  invalid factor level, NAs generated

> df <- data.frame(a = character(0), b=character(0), c=numeric(0), stringsAsFactors=F)

> df[nrow(df)+1,] <- c("d","gsgsgd",4)

> df
  a      b c
1 d gsgsgd 4

Wie in der vorherigen Antwort vorgeschlagen, lesen Sie die Spalten als Zeichen und machen die Umstellung auf Faktoren nach rbind. SQLFetch (Ich gehe davon aus RODBC ) hat auch die stringsAsFactors oder as.is Argument die Umwandlung von Zeichen zu steuern. Zulässige Werte sind wie für read.table, beispielsweise as.is=TRUE oder eine Spaltennummer.

Ich hatte das gleiche Problem mit Typ-Mismatches, insbesondere mit Faktoren. Ich musste zusammen zwei ansonsten kompatibel Datensätze kleben.

Meine Lösung ist es, Faktoren in beiden Datenrahmen zu „Charakter“ zu konvertieren. Dann funktioniert es wie ein Zauber: -)

    convert.factors.to.strings.in.dataframe <- function(dataframe)
    {
        class.data  <- sapply(dataframe, class)
        factor.vars <- class.data[class.data == "factor"]
        for (colname in names(factor.vars))
        {
            dataframe[,colname] <- as.character(dataframe[,colname])
        }
        return (dataframe)
    }

Wenn Sie wollen, dass die Arten in Ihrem zwei Datenrahmen laufen (ändern var Namen) sehen:

    cbind("orig"=sapply(allSurveyData, class), 
          "merge" = sapply(curSurveyDataMerge, class),
          "eq"=sapply(allSurveyData, class) == sapply(curSurveyDataMerge, class)
    )

Wenn Sie die Datenrahmen erstellen haben Sie die Wahl Ihre String-Spalten Faktoren machen (stringsAsFactors=T) oder sie als Zeichenketten zu halten.

Für Ihren Fall nicht Ihre String-Spalten Faktoren machen. Halten Sie sie als Strings, dann Anfügen funktioniert gut. Wenn Sie sie benötigen, um letztlich Faktoren zu sein, alles tun, das Einfügen und Anhängen zunächst als String und sie dann schließlich umwandeln zu berücksichtigen.

Wenn Sie die String-Spalten Faktoren machen und dann fügen Sie Zeilen ungesehen Werte enthalten, erhalten Sie den Fehler, den Sie auf jede neue unsichtbaren Faktor Ebene erwähnt, und dieser Wert wird mit NA ersetzt ...

> df <- data.frame(patient=c('Ann','Bob','Carol'), referring_doctor=c('X','Y','X'), stringsAsFactors=T)

  patient referring_doctor
1     Ann                X
2     Bob                Y
3   Carol                X

> df <- rbind(df, c('Denise','Z'))
Warning messages:
1: In `[<-.factor`(`*tmp*`, ri, value = "Denise") :
  invalid factor level, NA generated
2: In `[<-.factor`(`*tmp*`, ri, value = "Z") :
  invalid factor level, NA generated
> df
  patient referring_doctor
1     Ann                X
2     Bob                Y
3   Carol                X
4    <NA>             <NA>

So nicht Ihre String-Spalten Faktoren machen. Halten Sie sie als Strings, dann funktioniert gut anhängt:

> df <- data.frame(patient=c('Ann','Bob','Carol'), referring_doctor=c('X','Y','X'), stringsAsFactors=F)
> df <- rbind(df, c('Denise','Z'))
  patient referring_doctor
1     Ann                X
2     Bob                Y
3   Carol                X
4  Denise                Z

Um das Standardverhalten ändern :

options(stringsAsFactors=F)

So konvertiert einzelne Spalten zu / von String oder Faktor

df$col <- as.character(df$col)
df$col <- as.factor(df$col)

hier ist eine Funktion, um die gemeinsame Zeilen Namen von 2-Datenrahmen zu nehmen und eine rbind zu tun, wo wir im Grunde die Felder finden, die Faktoren sind, fügen Sie die neuen Faktoren dann die rbind tun. Diese sollten sich um einen beliebigen Faktor Fragen nehmen:

rbindCommonCols <-Funktion (x, y) {

commonColNames = intersect(colnames(x), colnames(y))
x = x[,commonColNames]
y = y[,commonColNames]

colClassesX = sapply(x, class)
colClassesY = sapply(y, class)
classMatch = paste( colClassesX, colClassesY, sep = "-" )
factorColIdx = grep("factor", classMatch)

for(n in factorColIdx){ 
    x[,n] = as.factor(x[,n])
    y[,n] = as.factor(y[,n])
}

for(n in factorColIdx){ 
    x[,n] = factor(x[,n], levels = unique(c( levels(x[,n]), levels(y[,n]) )))
    y[,n] = factor(y[,n], levels = unique(c( levels(y[,n]), levels(x[,n]) )))  
} 

res = rbind(x,y)
res

}

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top