r - واحد - يتم اضافة عمود باستخدام امر




تحويل الأعمدة data.frame من العوامل إلى الأحرف (9)

لدي إطار بيانات. دعونا نسميه bob :

> head(bob)
                 phenotype                         exclusion
GSM399350 3- 4- 8- 25- 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399351 3- 4- 8- 25- 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399352 3- 4- 8- 25- 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399353 3- 4- 8- 25+ 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399354 3- 4- 8- 25+ 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399355 3- 4- 8- 25+ 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-

أرغب في تسلسل صفوف إطار البيانات هذا (سيكون هذا سؤالاً آخر). لكن انظر:

> class(bob$phenotype)
[1] "factor"

أعمدة Bob هي العوامل. لذلك ، على سبيل المثال:

> as.character(head(bob))
[1] "c(3, 3, 3, 6, 6, 6)"       "c(3, 3, 3, 3, 3, 3)"      
[3] "c(29, 29, 29, 30, 30, 30)"

أنا لا أبدأ في فهم هذا ، ولكن أعتقد أن هذه هي مؤشرات في مستويات عوامل الأعمدة (من محكمة الملك caractacus) من bob ؟ ليس ما أحتاجه.

الغريب يمكن أن أذهب من خلال أعمدة bob يدويا ، والقيام به

bob$phenotype <- as.character(bob$phenotype)

الذي يعمل بشكل جيد. وبعد بعض الكتابة ، يمكنني الحصول على data.frame التي تكون الأعمدة أحرف بدلاً من العوامل. إذن ، سؤالي هو: كيف يمكنني القيام بذلك تلقائيًا؟ كيف يمكنني تحويل data.frame مع أعمدة عامل إلى data.frame بأعمدة أحرف دون الحاجة إلى الانتقال يدويًا في كل عمود؟

سؤال إضافي: لماذا يعمل المنهج اليدوي؟


أعلم أن هذه الإجابة متأخرة قليلاً ، ولكن إذا فهمت كيف يتم تخزين العوامل ، فيمكنك تجنب استخدام الوظائف المستندة إلى التطبيق لإنجاز ذلك. وهذا لا يعني على الإطلاق أن الحلول التطبيقية لا تعمل بشكل جيد.

يتم تنظيم العوامل كمؤشرات رقمية مرتبطة بقائمة "المستويات". يمكن ملاحظة ذلك إذا قمت بتحويل عامل إلى قيمة رقمية. وبالتالي:

> fact <- as.factor(c("a","b","a","d")
> fact
[1] a b a d
Levels: a b d

> as.numeric(fact)
[1] 1 2 1 3

الأرقام التي يتم إرجاعها في السطر الأخير تقابل مستويات العامل.

> levels(fact)
[1] "a" "b" "d"

لاحظ أن levels() بإرجاع صفيف من الأحرف. يمكنك استخدام هذه الحقيقة لتحويل العوامل بسهولة وسلاسة إلى سلاسل أو أرقام مثل:

> fact_character <- levels(fact)[as.numeric(fact)]
> fact_character
[1] "a" "b" "a" "d"

يعمل هذا أيضًا مع القيم الرقمية ، بشرط أن تقوم بتغليف التعبير الخاص بك في as.numeric() .

> num_fact <- factor(c(1,2,3,6,5,4))
> num_fact
[1] 1 2 3 6 5 4
Levels: 1 2 3 4 5 6
> num_num <- as.numeric(levels(num_fact)[as.numeric(num_fact)])
> num_num
[1] 1 2 3 6 5 4

أنا عادة ما تجعل هذه الوظيفة منفصلة عن جميع مشاريعي. سريع وسهل.

unfactorize <- function(df){
  for(i in which(sapply(df, class) == "factor")) df[[i]] = as.character(df[[i]])
  return(df)
}

إذا كنت data.table حزمة data.table للعمليات على data.frame فإن المشكلة غير موجودة.

library(data.table)
dt = data.table(col1 = c("a","b","c"), col2 = 1:3)
sapply(dt, class)
#       col1        col2 
#"character"   "integer" 

إذا كان لديك أعمدة عامل في مجموعة البيانات الخاصة بك بالفعل وتريد تحويلها إلى حرف يمكنك القيام بما يلي.

library(data.table)
dt = data.table(col1 = factor(c("a","b","c")), col2 = 1:3)
sapply(dt, class)
#     col1      col2 
# "factor" "integer" 
upd.cols = sapply(dt, is.factor)
dt[, names(dt)[upd.cols] := lapply(.SD, as.character), .SDcols = upd.cols]
sapply(dt, class)
#       col1        col2 
#"character"   "integer" 

إذا كنت تريد bobc لإطار بيانات جديد حيث يتم تحويل كل عامل متجه في bobf إلى متجه حرف ، فجرّب ذلك:

bobc <- rapply(bobf, as.character, classes="factor", how="replace")

إذا أردت بعد ذلك تحويله مرة أخرى ، يمكنك إنشاء متجه منطقي للأعمدة التي تعتبر عوامل ، واستخدام ذلك لتطبيق عامل بشكل انتقائي

f <- sapply(bobf, class) == "factor"
bobc[,f] <- lapply(bobc[,f], factor)

طريقة أخرى هي تحويله باستخدام تطبيق

bob2 <- apply(bob,2,as.character)

وأفضل واحد (السابق هو من "مصفوفة" الطبقة)

bob2 <- as.data.frame(as.matrix(bob),stringsAsFactors=F)

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

bob <- data.frame(lapply(bob, as.character), stringsAsFactors=FALSE)

سيؤدي هذا إلى تحويل كل المتغيرات إلى "صفة" صنف ، إذا كنت تريد فقط تحويل العوامل ، انظر حل ماريك أدناه .

كما يشيرhadley ، ما يلي هو أكثر إيجازا.

bob[] <- lapply(bob, as.character)

في كلتا الحالتين ، إخراج lapply قائمة؛ ومع ذلك ، بسبب الخصائص السحرية لـ R ، فإن استخدام [] في الحالة الثانية يحافظ على فئة data.frame لكائن bob ، وبالتالي يلغي الحاجة إلى التحويل مرة أخرى إلى data.frame باستخدام as.data.frame مع argumentAsFactors stringsAsFactors = FALSE .



هذا يعمل بالنسبة لي - وأخيرا برزت بطانة واحدة

df <- as.data.frame(lapply(df,function (y) if(class(y)=="factor" ) as.character(y) else y),stringsAsFactors=F)

تحديث: في ما يلي مثال على شيء لا ينجح. اعتقدت أنه من شأنه ، ولكن أعتقد أن الخيار stringsAsFactors يعمل فقط على سلاسل الأحرف - فإنه يترك العوامل وحدها.

جرب هذا:

bob2 <- data.frame(bob, stringsAsFactors = FALSE)

بشكل عام ، عندما تواجه مشاكل مع العوامل التي يجب أن تكون أحرفًا ، هناك stringsAsFactors مكان ما لمساعدتك (بما في ذلك الإعداد العام).





dataframe