ডেপ্লায়ার ব্যবহার করে ডেটাফ্রেমে সম্পূর্ণ কেসগুলির জন্য ফিল্টার করুন (কেস-ভিত্তিক মুছে ফেলা)


101

Dplyr ব্যবহার করে সম্পূর্ণ কেসগুলির জন্য কোনও ডেটা.ফ্রেম ফিল্টার করা সম্ভব? complete.casesঅবশ্যই সমস্ত ভেরিয়েবলের কাজগুলির একটি তালিকা সহ। তবে এটি ক) ভার্বোজ যখন প্রচুর ভেরিয়েবল থাকে এবং খ) ভেরিয়েবলের নামগুলি জানা না গেলে অসম্ভব (যেমন কোনও ফাংশনে যা কোনও ডেটাফ্রেম প্রসেস করে)।

library(dplyr)
df = data.frame(
    x1 = c(1,2,3,NA),
    x2 = c(1,2,NA,5)
)

df %.%
  filter(complete.cases(x1,x2))

4
complete.casesশুধু ভেক্টর গ্রহণ করে না। এটি পুরো ডেটা ফ্রেমও গ্রহণ করে।
জোড়ান

তবে এটি dplyrফিল্টার ফাংশনের অংশ হিসাবে কাজ করে না । আমার ধারণা আমি যথেষ্ট পরিষ্কার ছিলাম না এবং আমার প্রশ্ন আপডেট করেছি updated
ব্যবহারকারী2503795

4
আপনি যদি ডাইপ্লায়ারের সাথে ঠিক কীভাবে কাজ করে না তা প্রদর্শন করতে পারলে এটি সহায়তা করবে, কিন্তু আমি যখন ফিল্টার দিয়ে চেষ্টা করি তখন এটি ঠিক কাজ করে।
জোড়ান

উত্তর:


189

এটা চেষ্টা কর:

df %>% na.omit

অথবা এটা:

df %>% filter(complete.cases(.))

অথবা এটা:

library(tidyr)
df %>% drop_na

আপনি যদি কোনও ভেরিয়েবলের নিখোঁজের উপর ভিত্তি করে ফিল্টার করতে চান তবে শর্তসাপেক্ষ ব্যবহার করুন:

df %>% filter(!is.na(x1))

বা

df %>% drop_na(x1)

অন্যান্য উত্তরগুলি বোঝায় যে উপরের সমাধানগুলির সমাধানগুলি na.omitঅনেক ধীর গতিযুক্ত তবে এটির তুলনায় ভারসাম্য বজায় রাখতে হবে যে এটি বৈশিষ্ট্যের মধ্যে বাদ দেওয়া সারিগুলির সারি সূচকগুলি দেয় na.actionযখন উপরের অন্যান্য সমাধানগুলি দেয় না।

str(df %>% na.omit)
## 'data.frame':   2 obs. of  2 variables:
##  $ x1: num  1 2
##  $ x2: num  1 2
##  - attr(*, "na.action")= 'omit' Named int  3 4
##    ..- attr(*, "names")= chr  "3" "4"

যোগ হয়েছে dplyr এবং মন্তব্যগুলির সর্বশেষ সংস্করণ প্রতিফলিত করার জন্য আপডেট হয়েছে

সংযোজন এবং মন্তব্যগুলির সর্বশেষ সংস্করণ প্রতিবিম্বিত করতে আপডেট হয়েছে


স্রেফ উত্তর দিতে ফিরে এসে আপনার দরকারী উত্তরটি দেখেছেন!
কুফরী

4
ধন্যবাদ! আমি কিছু বেঞ্চমার্ক ফলাফল যুক্ত করেছি। na.omit()বেশ খারাপ অভিনয় করে তবে একটি দ্রুত হয়।
ব্যবহারকারী2503795

4
এটি এখন পাশাপাশি কাজ করে: df %>% filter(complete.cases(.))। নিশ্চিত নয় যে dplyr এর সাম্প্রতিক পরিবর্তনগুলি এটি সম্ভব করেছে কিনা।
ব্যবহারকারী2503795

@ জন-ক্যাটিনস যেমন উল্লেখ করেছেন, তেমন বিপর্যয় ফাংশন বলা হয় drop_na , তাই আপনি এখন কি করতে পারেন: df %>% drop_na()
সিবিএনআর

26

এটি আমার পক্ষে কাজ করে:

df %>%
  filter(complete.cases(df))    

বা আরও কিছু সাধারণ:

library(dplyr) # 0.4
df %>% filter(complete.cases(.))

এটির সুবিধা হবে যে ফিল্টারটিতে যাওয়ার আগে ডেটা চেইনে পরিবর্তন করা যেতে পারে।

আরও কলাম সহ আরও একটি মানদণ্ড:

set.seed(123)
x <- sample(1e5,1e5*26, replace = TRUE)
x[sample(seq_along(x), 1e3)] <- NA
df <- as.data.frame(matrix(x, ncol = 26))
library(microbenchmark)
microbenchmark(
  na.omit = {df %>% na.omit},
  filter.anonymous = {df %>% (function(x) filter(x, complete.cases(x)))},
  rowSums = {df %>% filter(rowSums(is.na(.)) == 0L)},
  filter = {df %>% filter(complete.cases(.))},
  times = 20L,
  unit = "relative")

#Unit: relative
#             expr       min        lq    median         uq       max neval
 #         na.omit 12.252048 11.248707 11.327005 11.0623422 12.823233    20
 #filter.anonymous  1.149305  1.022891  1.013779  0.9948659  4.668691    20
 #         rowSums  2.281002  2.377807  2.420615  2.3467519  5.223077    20
 #          filter  1.000000  1.000000  1.000000  1.0000000  1.000000    20

4
আমি আপনার উত্তরটি "দিয়ে আপডেট করেছি।" সম্পূর্ণ.কম এবং যুক্ত মানদণ্ডে - আশা করি আপনি কিছু মনে করবেন না :-)
তালাত

:) আমি না। ধন্যবাদ.
মিহা ট্রয়েট

4
আমি df %>% slice(which(complete.cases(.)))উপরের মানদণ্ডে ফিল্টার-পদ্ধতির চেয়ে 20% বেশি দ্রুত সম্পাদন করেছি ।
তালাত

এটি লক্ষণীয় যে আপনি যদি এই ফিল্টারটি dplyr পাইপে অন্য dplyr কমান্ড (যেমন গ্রুপ_বি ()) এর সাথে ব্যবহার করে থাকেন তবে %>% data.frame() %>%আপনাকে চেষ্টা করার পূর্বে সংযোজন করতে হবে এবং সম্পূর্ণ কোডেস (।) এ ফিল্টার করতে হবে কারণ এটি কাজ করবে না because টিবলস বা গোষ্ঠীযুক্ত টিবল বা কিছু। বা কমপক্ষে, আমার অভিজ্ঞতা হয়েছে।
সি। ডেনি

16

গ্রোথেন্ডিকের জবাবের জন্য এখানে কিছু মানদণ্ডের ফলাফল রয়েছে। na.omit () অন্যান্য দুটি সমাধানের মতো 20x সময় নেয়। আমি মনে করি ডিপিপ্লায়ারের ফিল্টারটির অংশ হিসাবে এটির জন্য যদি কোনও ফাংশন থাকে তবে এটি ভাল হবে।

library('rbenchmark')
library('dplyr')

n = 5e6
n.na = 100000
df = data.frame(
    x1 = sample(1:10, n, replace=TRUE),
    x2 = sample(1:10, n, replace=TRUE)
)
df$x1[sample(1:n, n.na)] = NA
df$x2[sample(1:n, n.na)] = NA


benchmark(
    df %>% filter(complete.cases(x1,x2)),
    df %>% na.omit(),
    df %>% (function(x) filter(x, complete.cases(x)))()
    , replications=50)

#                                                  test replications elapsed relative
# 3 df %.% (function(x) filter(x, complete.cases(x)))()           50   5.422    1.000
# 1               df %.% filter(complete.cases(x1, x2))           50   6.262    1.155
# 2                                    df %.% na.omit()           50 109.618   20.217

12

এটি একটি সংক্ষিপ্ত ফাংশন যা আপনাকে কলামগুলি নির্দিষ্ট করতে দেয় (মূলত যা কিছু dplyr::select বুঝতে পারে) যার কোনও এনএ মান থাকতে পারে না (প্যান্ডাস ডিএফ.প্রোপনা () এর পরে মডেলিং ):

drop_na <- function(data, ...){
    if (missing(...)){
        f = complete.cases(data)
    } else {
        f <- complete.cases(select_(data, .dots = lazyeval::lazy_dots(...)))
    }
    filter(data, f)
}

[ ড্রপ_না এখন পরিপাচারের অংশ: উপরেরগুলি দ্বারা প্রতিস্থাপন করা যেতে পারে library("tidyr")]

উদাহরণ:

library("dplyr")
df <- data.frame(a=c(1,2,3,4,NA), b=c(NA,1,2,3,4), ac=c(1,2,NA,3,4))
df %>% drop_na(a,b)
df %>% drop_na(starts_with("a"))
df %>% drop_na() # drops all rows with NAs

0.5 এর মতো একটি কাট অফ যুক্ত করতে এবং কলাম দ্বারা এটি প্রক্রিয়া করতে আরও বেশি কার্যকর হবে না? কেস: 50% এবং অদৃশ্য ডেটা দিয়ে ভেরিয়েবলগুলি নির্মূল করুন। উদাহরণ: ডেটা [, -যাহা (কলিমিয়ানস (is.na (ডেটা))> ০.৫%] পরিপাটি করে এটি করতে পেরে ভাল লাগবে।
মন্ডুইজ

@ মন্ডুইজ এর অর্থ হ'ল পাইপলাইনের পরবর্তী ধাপে আরও তথ্যের সংযোজন (যেখানে কোনও ভেরিয়েবলের তখন প্রচুর এনএ থাকে) ব্যর্থ হতে পারে কারণ প্রয়োজনীয় ভেরিয়েবলটি এখন অনুপস্থিত ...
জানু ক্যাটিনস

ঠিক আছে, এটা বোঝা যায়।
মন্ডুইজ

6

এটা চেষ্টা কর

df[complete.cases(df),] #output to console

বা এটিও

df.complete <- df[complete.cases(df),] #assign to a new data.frame

উপরের কমান্ডগুলি আপনার ডেটা.ফ্রেমে সমস্ত কলাম (ভেরিয়েবল) এর সম্পূর্ণতার জন্য যাচাইয়ের যত্ন নেয়।


ধন্যবাদ আমি অনুমান করি যদিও আমি যথেষ্ট পরিষ্কার ছিলাম না (প্রশ্ন আপডেট হয়েছে)। আমি সম্পূর্ণ কোডেস (ডিএফ) সম্পর্কে জানি তবে dplyrফিল্টার ফাংশনের অংশ হিসাবে এটি করতে চাই । এটি ডিপ্লাইর চেইন ইত্যাদিতে একটি ঝরঝরে সংহতকরণের অনুমতি দেবে
ব্যবহারকারী 2503795

@ জি.গ্রোথেন্ডিক
উত্তর

ইন dplyr:::do.data.frameবিবৃতি env$. <- .dataপরিবেশ ডট যোগ করা হয়েছে। ম্যাজিটারে এরকম কোনও বক্তব্য :: "%>%" `
জি গ্রোথেন্ডিক

দুঃখিত অবশ্যই মন্তব্য ভুল জায়গায় প্রবেশ করা আবশ্যক।
জি গ্রোথেন্ডিক

3

কেবল সম্পূর্ণতার জন্য, সম্পূর্ণরূপে dplyr::filterএড়ানো যেতে পারে তবে কেবল magrittr:extract(একটি উপনাম [) ব্যবহার করে চেইন রচনা করতে সক্ষম হন :

library(magrittr)
df = data.frame(
  x1 = c(1,2,3,NA),
  x2 = c(1,2,NA,5))

df %>%
  extract(complete.cases(.), )

অতিরিক্ত বোনাস হ'ল গতি, এটি filterএবং na.omitরূপগুলির মধ্যে দ্রুততম পদ্ধতি (@ মিহা ট্রয়েট মাইক্রোব্যাঙ্কমার্ক ব্যবহার করে পরীক্ষা করা)।


আমি যখন মিহা ট্রয়েটের ডেটা দিয়ে মানদণ্ডটি করি, তখন আমি দেখতে পাচ্ছি যে ব্যবহারটি extract()প্রায় দশগুণ বেশি ধীর filter()। যাইহোক, যখন আমি এর সাথে একটি ছোট ডেটা ফ্রেম তৈরি করি df <- df[1:100, 1:10], তখন চিত্রটি পরিবর্তন extract()হয় এবং দ্রুত test
স্টিবু

আপনি সঠিক. দেখে মনে হচ্ছে magrittr::extractকেবলমাত্র n <= 5e3মিহা ট্রয়েট বেঞ্চমার্কের মধ্যেই দ্রুততম পথ ।
এমবাস্ক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.