보이지 않는 문자열 값이 있는 새 레코드를 데이터 프레임에 추가할 때 보이지 않는 요소 수준으로 인해 경고가 발생하고 NA가 발생합니다.

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

  •  06-07-2019
  •  | 
  •  

문제

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실제 값 대신

나는 다음과 같이 가정한다:

  1. 다른 R/RODBC 버전으로 이전 데이터를 생성하므로 유형이 다른 방법(다른 설정 - 소수 구분 기호)으로 생성되었습니다.
  2. 문제가 있는 열에 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

}

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top