보이지 않는 문자열 값이 있는 새 레코드를 데이터 프레임에 추가할 때 보이지 않는 요소 수준으로 인해 경고가 발생하고 NA가 발생합니다.
문제
2001년부터 2007년까지의 청구 데이터가 포함된 데이터 프레임(14.5K 행 x 15열)이 있습니다.
다음과 같이 새로운 2008년 데이터를 추가합니다. alltime <- rbind(alltime,all2008)
불행히도 경고가 생성됩니다.
> Warning message:
In `[<-.factor`(`*tmp*`, ri, value = c(NA, NA, NA, NA, NA, NA, NA, :
invalid factor level, NAs generated
내 생각에는 이전 데이터 프레임에 이름이 없는 새로운 환자가 있으므로 해당 환자에게 어떤 수준을 제공해야 할지 알 수 없는 것 같습니다.마찬가지로 '의뢰 의사' 열에 표시되지 않는 새로운 이름이 있습니다.
해결책은 무엇입니까?
해결책
두 가지 유형의 불일치로 인해 발생할 수 있습니다. 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)))
.그러나 두 번째 data.frame 열에 있는 경우에는 요소가 아닙니다. levels(x2)
~이다 NULL
, 레벨이 확장되지 않습니다.
이는 출력 데이터가 잘못되었음을 의미합니다!있다 NA
실제 값 대신
나는 다음과 같이 가정한다:
- 다른 R/RODBC 버전으로 이전 데이터를 생성하므로 유형이 다른 방법(다른 설정 - 소수 구분 기호)으로 생성되었습니다.
- 문제가 있는 열에 NULL 또는 특정 데이터가 있습니다.누군가 데이터베이스에서 열을 변경합니다.
해결책:
잘못된 열을 찾아 해당 열이 잘못되고 수정된 이유를 찾으세요.증상이 아닌 원인을 제거하십시오.
다른 팁
"쉬운"방법은 텍스트 데이터를 가져올 때 문자열을 요소로 설정하지 않는 것입니다.
주목하십시오 read.{table,csv,...}
기능은 a stringsAsFactors
기본적으로 설정된 매개 변수 TRUE
. 이것을 설정할 수 있습니다 FALSE
수입하는 동안 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
또는 일부 열 번호.
나는 유형 불일치, 특히 요인과 같은 문제가있었습니다. 다른 두 가지 호환 데이터 세트를 함께 붙여야했습니다.
내 해결책은 두 데이터 프레임의 요인을 "문자"로 변환하는 것입니다. 그런 다음 매력처럼 작동합니다 :-)
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)
}
두 데이터 프레임에서 실행되는 유형을 보려면 (var 이름 변경) :
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 <- 기능 (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
}