未表示の文字列値を持つ新しいレコードをデータフレームに追加すると、未表示の因子レベルが発生し、警告が発生し、結果はNAになります
質問
2001年から2007年までの請求データを含むデータフレーム(14.5K行15列)があります。
alltime <- rbind(alltime,all2008)
残念ながら警告が発生します:
> Warning message:
In `[<-.factor`(`*tmp*`, ri, value = c(NA, NA, NA, NA, NA, NA, NA, :
invalid factor level, NAs generated
私の推測では、以前のデータフレームに名前がなかった新しい患者がいるため、それらの患者にどのレベルを与えるかがわからないでしょう。同様に、「紹介医師」列にある新しい目に見えない名前。
解決策は何ですか?
解決
2つのdata.frames
の型の不一致が原因である可能性があります。
最初にすべてのチェックタイプ(クラス)。診断目的でこれを行います:
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)
)
次のような行があると思います:
alltime all2008 new2old old2new
... ... ... ... ...
some_column "factor" "numeric" "factor" "character"
... ... ... ... ...
その場合、説明:
rbind
タイプの一致をチェックしません。 rbind.data.frame
コードを分析すると、最初の引数が出力タイプを初期化したことがわかります。最初のdata.frameタイプが因子である場合、出力data.frame列はレベルunique(c(levels(x1),levels(x2)))
の因子です。しかし、2番目のdata.frame列が因子でない場合、levels(x2)
はNULL
であるため、レベルは拡張されません。
出力データが間違っていることを意味します!真の値の代わりにNA
があります
次のように思います:
- 別のR / RODBCバージョンを使用して古いデータを作成するため、タイプは異なるメソッド(異なる設定-小数点区切り記号など)で作成されました
- たとえば、問題のある列にNULLまたは特定のデータがあります。誰かがデータベースの下の列を変更します。
解決策:
間違った列を見つけ、それが間違っていて修正された理由を見つけます。症状ではなく原因を取り除きます。
他のヒント
<!> quot; easy <!> quot;方法は、テキストデータをインポートするときに、文字列を要素として設定しないようにすることです。
read.{table,csv,...}
関数は、デフォルトでstringsAsFactors
に設定されるTRUE
パラメーターを受け取ることに注意してください。これをデータのインポートおよびFALSE
-ing中にrbind
に設定できます。
列を最後の要素として設定する場合は、それも実行できます。
例:
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)stringsAsFactorをFALSEに設定してデータフレームを作成します。これで要因の問題が解決するはずです
2)その後、rbindを使用しない-データフレームが空の場合、列名を台無しにします。単純に次のようにします:
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
前の回答で示唆されたように、列を文字として読み取り、rbind
の後の係数に変換します。
SQLFetch
(私は RODBC と仮定)には、文字の変換を制御するstringsAsFactors
またはas.is
引数もあります。
許可される値は、read.table
の場合、たとえばas.is=TRUE
または何らかの列番号です。
型の不一致、特に要因に関して同じ問題がありました。互換性のない2つのデータセットを結合する必要がありました。
私の解決策は、両方のデータフレームの係数を<!> quot; character <!> quot;に変換することです。それは魅力のように動作します:-)
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)
}
2つのデータフレームの実行中の型を確認する場合(変数名を変更する):
cbind("orig"=sapply(allSurveyData, class),
"merge" = sapply(curSurveyDataMerge, class),
"eq"=sapply(allSurveyData, class) == sapply(curSurveyDataMerge, class)
)
データフレームを作成するとき、文字列の列の要素(stringsAsFactors=T
)にするか、文字列として保持するかを選択できます。
あなたの場合、文字列の列を考慮に入れないでください。それらを文字列として保持すると、追加は正常に機能します。最終的に要素にする必要がある場合は、最初にすべての挿入と追加を文字列として行い、最後に要素に変換します。
文字列の列を因数分解し、未表示の値を含む行を追加すると、新しい未表示の要因レベルごとに言及したエラーが発生し、その値はNAに置き換えられます...
> 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>
したがって、文字列の列を考慮に入れないでください。それらを文字列として保持し、追加しても問題なく動作します:
> 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
デフォルトの動作を変更するには:
options(stringsAsFactors=F)
個々の列を文字列または因子との間で変換するには
df$col <- as.character(df$col)
df$col <- as.factor(df$col)
ここでは、2つのデータフレームの共通行名を取得し、基本的にファクターであるフィールドを見つけるrbindを実行し、新しいファクターを追加してからrbindを実行する関数があります。これにより、要因の問題に対処する必要があります。
rbindCommonCols <!> lt; -function(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
}