কেবলমাত্র এনএ থাকা কলামগুলি কীভাবে মুছবেন?


83

আমার কাছে একটি ডেটা ফ্রেম রয়েছে যাতে সমস্ত এনএ মান সহ কিছু কলাম রয়েছে, আমি কীভাবে সেগুলি ডেটা.ফ্রেম থেকে মুছতে পারি।

আমি কি ফাংশনটি ব্যবহার করতে পারি?

na.omit(...) 

কিছু অতিরিক্ত যুক্তি উল্লেখ করে?


4
হাই! আপনার পোস্ট পুনরুত্পাদনযোগ্য করুন দয়া করে। পোস্টটি পড়ুন কিভাবে একটি দুর্দান্ত গঠনকর উদাহরণ করতে কিভাবে এই করতে হবে সেই বিষয়ে। ধন্যবাদ.
অরুণ

এই পোস্টে সাহায্য করে? stackoverflow.com/questions/4862178/…
অরুণ

আপনি কি পোস্ট করতে পারেন head(data)? আপনি কি সংশ্লিষ্ট কলাম বা সারিগুলি সরাতে চান?
নিশান্ত

@ e4e5f4 আমি সংশ্লিষ্ট কলামগুলি অপসারণ করতে চাই (যে কলামগুলির আমি মুছে ফেলতে চাই তার সমস্ত মান হ'ল এনএ)
লরেঞ্জো রিগামন্তি

উত্তর:


123

এটি করার একটি উপায়:

df[, colSums(is.na(df)) != nrow(df)]

যদি কোনও কলামে এনএর গণনা সারি সংখ্যার সমান হয় তবে এটি অবশ্যই সম্পূর্ণ এনএ হতে হবে।

বা একইভাবে

df[colSums(!is.na(df)) > 0]

4
আমি কীভাবে এনএ এর প্রান্তিকের চেয়ে বেশি কলামগুলি মুছতে পারি? বা শতাংশে (50% এর উপরে বলতে পারি)?
শৃঙ্খলা

4
@ ল্যাভেডিনাস্টি সম্ভবত আপনার মন্তব্য পোস্ট করার পরে আপনি ইতিমধ্যে নি বলে ধরে নিচ্ছেন একটি পৃথক প্রশ্ন জমা দেওয়া ভাল। তবে যাইহোক, আপনি সর্বদা এমন কিছু করতে পারেন df[, colSums(is.na(df)) < nrow(df) * 0.5]যেমন কমপক্ষে কমপক্ষে 50% নন-ফাঁকা জায়গায় কলামগুলি রাখুন।
সিয়ারন টোবিন

4
একটি df[, colSums(is.na(df)) != nrow(df) - 1]1
স্বাবলম্ব

9
এটি dplyr (সংস্করণ ০.০.০) এর সাথে সিলেক্ট_আইএফ ফাংশনটিও ব্যবহার করতে পারেন। df %>% select_if(colSums(!is.na(.)) > 0)
স্টেফান আভে

@ ম্যাডস্কোন এটি আমাকে "," ডিএফ [, কলসুমস (আইসনা (ডিএফ)) এর জন্য সিনট্যাক্স ত্রুটি দিচ্ছে! ডিএফ [কলসসুমস (! is.na (df))> 0] এ। আমি কি কিছু মিস করছি
অরবিন্দ এস

53

এখানে একটি dplyr সমাধান:

df %>% select_if(~sum(!is.na(.)) > 0)

আপডেট করুন:summarise_if() ফাংশনের যেমন ছাপিয়ে হয় dplyr 1.0। এখানে আরও দুটি সমাধান দেওয়া হয়েছে যা where()পরিপাটি ফাংশনটি ব্যবহার করে :

df %>% 
  select(
    where(
      ~sum(!is.na(.x)) > 0
    )
  )
df %>% 
  select(
    where(
      ~!all(is.na(.x))
    )
  )

4
K 15k সারি এবং k 5k কলামে, এটি সত্যই চিরকালের জন্য নিচ্ছে।
এনগ্রিস্টুডেন্ট

@ এঙ্গারস্টুডেন্ট গৃহীত উত্তরের সমাধানের সাথে কি এটি দ্রুত ছিল?
জনি

বহু বছর কেটে গেছে। মনে নেই। ডিজেভির নীচে একটি সুন্দর টাইমিং পোস্ট রয়েছে।
এংগ্রস্টুডেন্ট


24

দেখে মনে হচ্ছে আপনি কেবল সমস্ত কলামগুলিই সরিয়ে ফেলতে চান এবং NAকিছু সারি দিয়ে কলামগুলি NAরেখেছেন। আমি এটি করব (তবে আমি নিশ্চিত যে একটি কার্যকর ভেক্টরাইজড স্যুশন রয়েছে:

#set seed for reproducibility
set.seed <- 103
df <- data.frame( id = 1:10 , nas = rep( NA , 10 ) , vals = sample( c( 1:3 , NA ) , 10 , repl = TRUE ) )
df
#      id nas vals
#   1   1  NA   NA
#   2   2  NA    2
#   3   3  NA    1
#   4   4  NA    2
#   5   5  NA    2
#   6   6  NA    3
#   7   7  NA    2
#   8   8  NA    3
#   9   9  NA    3
#   10 10  NA    2

#Use this command to remove columns that are entirely NA values, it will elave columns where only some vlaues are NA
df[ , ! apply( df , 2 , function(x) all(is.na(x)) ) ]
#      id vals
#   1   1   NA
#   2   2    2
#   3   3    1
#   4   4    2
#   5   5    2
#   6   6    3
#   7   7    2
#   8   8    3
#   9   9    3
#   10 10    2

আপনি যদি এমন পরিস্থিতিতে নিজেকে খুঁজে পান যেখানে আপনি কোনও NAমান রয়েছে এমন কলামগুলি মুছে ফেলতে চান তবে আপনি কেবল allউপরের আদেশটি পরিবর্তন করতে পারেন any


ডেটা.ফ্রেমে দুটি ধরণের কলাম রয়েছে: এক হ্যাচসিটিতে সমস্ত মান হ'ল এবং অন্যটিতে সমস্ত মান হ'ল এনএ
লরেঞ্জো রিগামন্তি

সুতরাং এটি তখন কাজ করবে। এটি সমস্ত কলামগুলি কেবল কলামগুলি সরিয়ে দেয় NA
সাইমন ও'হানলন

4
ভাল সমাধান। এবার কি করবো apply(is.na(df), 1, all)যদিও মাত্র কারণ এটি সামান্য neater এবং is.na()সব ব্যবহার করা হয় dfএকটি সময়ে বদলে এক সারি (প্রদর্শনী একটু দ্রুততর হবে)।
সিয়ারন টোবিন

@ ম্যাডস্কোন ভাল টিপস - সুন্দর দেখায়। আপনার সারি সারি নয় কলামগুলি জুড়ে প্রয়োগ করা উচিত।
সাইমন ও'হানলন

@ ম্যাডস্কোন সম্পাদনাগুলি মন্তব্যে 5 মিনিটের পরে লক হয়ে যায়। আমার চিন্তা করা উচিত নয়, এটি কোনও বড় কথা নয় !! :-)
সাইমন ও'হানলন

20

একটি স্বজ্ঞামূলক স্ক্রিপ্ট: dplyr::select_if(~!all(is.na(.)))। এটি আক্ষরিকভাবে কেবল-সমস্ত-উপাদান-অনুপস্থিত কলামগুলি রাখে। (সমস্ত উপাদান-অনুপস্থিত কলামগুলি মুছতে)।

> df <- data.frame( id = 1:10 , nas = rep( NA , 10 ) , vals = sample( c( 1:3 , NA ) , 10 , repl = TRUE ) )

> df %>% glimpse()
Observations: 10
Variables: 3
$ id   <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
$ nas  <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA
$ vals <int> NA, 1, 1, NA, 1, 1, 1, 2, 3, NA

> df %>% select_if(~!all(is.na(.))) 
   id vals
1   1   NA
2   2    1
3   3    1
4   4   NA
5   5    1
6   6    1
7   7    1
8   8    2
9   9    3
10 10   NA

17

সাথে অন্য একটি বিকল্প Filter

Filter(function(x) !all(is.na(x)), df)

দ্রষ্টব্য: @ সিমন ও'হানলনের পোস্ট থেকে ডেটা।


5

যেহেতু পারফরম্যান্স আমার জন্য সত্যই গুরুত্বপূর্ণ ছিল, আমি উপরের সমস্ত ফাংশনগুলিকে বেঞ্চমার্ক করেছি।

দ্রষ্টব্য: @ সিমন ও'হানলনের পোস্ট থেকে ডেটা। শুধুমাত্র 10 এর পরিবর্তে 15000 আকারে।

library(tidyverse)
library(microbenchmark)

set.seed(123)
df <- data.frame(id = 1:15000,
                 nas = rep(NA, 15000), 
                 vals = sample(c(1:3, NA), 15000,
                               repl = TRUE))
df

MadSconeF1 <- function(x) x[, colSums(is.na(x)) != nrow(x)]

MadSconeF2 <- function(x) x[colSums(!is.na(x)) > 0]

BradCannell <- function(x) x %>% select_if(~sum(!is.na(.)) > 0)

SimonOHanlon <- function(x) x[ , !apply(x, 2 ,function(y) all(is.na(y)))]

jsta <- function(x) janitor::remove_empty(x)

SiboJiang <- function(x) x %>% dplyr::select_if(~!all(is.na(.)))

akrun <- function(x) Filter(function(y) !all(is.na(y)), x)

mbm <- microbenchmark(
  "MadSconeF1" = {MadSconeF1(df)},
  "MadSconeF2" = {MadSconeF2(df)},
  "BradCannell" = {BradCannell(df)},
  "SimonOHanlon" = {SimonOHanlon(df)},
  "SiboJiang" = {SiboJiang(df)},
  "jsta" = {jsta(df)}, 
  "akrun" = {akrun(df)},
  times = 1000)

mbm

ফলাফল:

Unit: microseconds
         expr    min      lq      mean  median      uq      max neval  cld
   MadSconeF1  154.5  178.35  257.9396  196.05  219.25   5001.0  1000 a   
   MadSconeF2  180.4  209.75  281.2541  226.40  251.05   6322.1  1000 a   
  BradCannell 2579.4 2884.90 3330.3700 3059.45 3379.30  33667.3  1000    d
 SimonOHanlon  511.0  565.00  943.3089  586.45  623.65 210338.4  1000  b  
    SiboJiang 2558.1 2853.05 3377.6702 3010.30 3310.00  89718.0  1000    d
         jsta 1544.8 1652.45 2031.5065 1706.05 1872.65  11594.9  1000   c 
        akrun   93.8  111.60  139.9482  121.90  135.45   3851.2  1000 a


autoplot(mbm)

এখানে চিত্র বর্ণনা লিখুন

mbm %>% 
  tbl_df() %>%
  ggplot(aes(sample = time)) + 
  stat_qq() + 
  stat_qq_line() +
  facet_wrap(~expr, scales = "free")

এখানে চিত্র বর্ণনা লিখুন


কখনও কখনও প্রথম পুনরাবৃত্তিটি একটি জেআইটি সংকলিত হয়, সুতরাং এটির সময় খুব খারাপ, এবং খুব বৈশিষ্ট্যযুক্ত নয়। আমি মনে করি এটি আকর্ষণীয় বৃহত্তর নমুনার আকার বিতরণের সঠিক লেজগুলিতে কী করে। এটি ভাল কাজ।
EngrStudent

আমি আবার এটি চালাচ্ছি, নিশ্চিত ছিল না যে আমি চক্রান্তটি পরিবর্তন করেছি। সত্যিই বিতরণ সম্পর্কে। আমার যখন সময় হবে তখন আমার সম্ভবত বিভিন্ন নমুনার আকারের তুলনা করা উচিত।
ডিজেভি 5'20

4
যদি আপনি qqplot ( ggplot2.tidyverse.org/references/geom_qq.html ) ট্রেন্ডগুলির মধ্যে একটি, যেমন "আকরুন" থাকে তবে আমি বাজি ধরছি একটি পয়েন্ট রয়েছে যা বাকী বিতরণ থেকে খুব আলাদা। বাকী অংশটি প্রতিনিধিত্ব করে যদি আপনি এটি বারবার চালনা করেন তবে এটি একবার উপস্থাপন করে তবে কী ঘটে তা প্রতিনিধিত্ব করে। একটি পুরানো প্রবাদ আছে: আপনার 20 বছরের অভিজ্ঞতা থাকতে পারে বা আপনি কেবল এক বছরের মূল্যবান অভিজ্ঞতা 20 বার থাকতে পারেন।
EngrStudent

খুব সুন্দর! আমি বেশ কয়েকটা নমুনা চরম লেজে থাকায় অবাক হয়েছি। আমি ভাবছি কেন এটি এত বেশি ব্যয়বহুল। জেআইটি 1 বা 2 হতে পারে তবে 20 নয়। শর্ত? বাধা? অন্য? আপডেটের জন্য আবার ধন্যবাদ।
EngrStudent

আপনাকে স্বাগতম, ভাবনার জন্য আপনাকে ধন্যবাদ। জানেন না, আমি আসলে এটি "অবাধে" চালানোর অনুমতি দিয়েছিলাম।
ডিজেভি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.