سؤال
ولدي CSV من ملف البيانات التي يمكنني تحميل في R باستخدام read.csv()
وبعض البيانات مفقود، لذلك أريد للحد من إطار البيانات وصولا الى وضع الذي يتكون بالكامل من بيانات ناقصة، أي إذا ظهر NULL
في أي مكان، أريد أن استبعاد هذا العمود والصف من مجموعة البيانات المصفاة .
وأنا أعلم أنني ربما تستطيع أن تفعل ذلك ببساطة إلى حد ما مع عمليات R ناقلات يحمل في ثناياه عوامل، لكنني لست متأكدا تماما كيفية القيام بذلك بالضبط؟
لجعل سؤالي قليلا أكثر واقعية، وهنا عينة سريعة للبيانات حتى تستطيع أن ترى ما أريد القيام به.
DocID Anno1 Anno7 Anno8
1 7 NULL 8
2 8 NULL 3
44 10 2 3
45 6 6 6
46 1 3 4
49 3 8 5
62 4 NULL 9
63 2 NULL 4
67 11 NULL 3
91 NULL 9 7
92 NULL 7 5
93 NULL 8 8
وهكذا تعطى هذه المدخلات، وانا بحاجة الى بعض التعليمات البرمجية التي سيتم خفض الانتاج لذلك.
DocID Anno8
44 3
45 6
46 4
49 5
وكما Anno8
هو العمود الوحيد مع بيانات غير فارغة، وهناك فقط أربعة صفوف مع البيانات غير فارغة.
المحلول
إذا x
هو data.frame
(أو matrix
) ثم
x[ ,apply(x, 2, function(z) !any(is.na(z)))]
ومنذ يستخدم المثال الخاص بك NULL
، سيتم استبدال is.na(·)
التي كتبها is.null(·)
وبدلا من ذلك يمكنك أن تبحث في subset(·)
.
نصائح أخرى
ويمكنك إسقاط أي صف يحتوي على المفقودين باستخدام na.omit ()، ولكن هذا ليس ما تريد. وعلاوة على ذلك، فإن الجواب المقبولة حاليا هي خاطئة. فهو يوفر لك الأعمدة كاملة، ولكن لا إسقاط الصفوف التي تحتوي على واحد أو أكثر من القيم المفقودة، وهو ما سئل عنه. ويمكن الحصول على الإجابة الصحيحة على النحو التالي:
> a <- data.frame(a=c(1,2),b=c(NA,1), c=c(3,4))
> a
a b c
1 1 NA 3
2 2 1 4
> na.omit(a)[,colSums(is.na(a))==0]
a c
2 2 4
لنرى أن الإجابة أعلاه خاطئة:
> a[ ,apply(a, 2, function(z) !any(is.na(z)))]
a c
1 1 3
2 2 4
والصف 1 يجب أن يكون إسقاط بسبب NA في العمود 2.
a <- data.frame(a=c(1,2,0,1),b=c(NA,1,NA,1), c=c(3,4,5,1))
na.omit(a)
a b c
2 2 1 4
4 1 1 1
a[rowSums(is.na(a))==0,]
a b c
2 2 1 4
4 1 1 1
a[complete.cases(a),]
a b c
2 2 1 4
4 1 1 1
وبالإضافة إلى ذلك، يمكنك القيام بذلك باستخدام مكتبة sqldf
، إذا x
هو dataframe الخاص بك:
library(sqldf)
result <- sqldf("SELECT DocID, Anno8 FROM x
WHERE Anno1 IS NOT NULL AND Anno7 IS NOT NULL")