مستويات العامل غير المرئية عند إلحاق سجلات جديدة بقيم سلسلة غير مرئية إلى إطار بيانات، تسبب تحذيرًا وتؤدي إلى NA

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

  •  06-07-2019
  •  | 
  •  

سؤال

لدي إطار بيانات (14.5 ألف صف في 15 عمودًا) يحتوي على بيانات الفواتير من عام 2001 إلى عام 2007.

أقوم بإلحاق بيانات 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,...} تأخذ معلمة 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 أو بعض رقم العمود.

وكان لي نفس المشكلة مع نوع عدم التطابق، وخاصة مع العوامل. كان لي لالغراء معا مجموعتين من البيانات متوافقة على خلاف ذلك.

وبلدي الحل هو تحويل العوامل في كل dataframes إلى "الطابع". ثم يعمل مثل السحر: -)

    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)
    }

إذا كنت تريد أن ترى أنواع في الخاص بك اثنين dataframes تشغيل (أسماء تغيير فار):

    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 <-function (س، ص) {

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