Ištrinkite eilutes su visais arba kai kuriais NA (trūkstamų reikšmių) duomenimis

Norėčiau ištrinti šios duomenų rėmelio eilutes, kurios:

a) visuose stulpeliuose yra NA . Toliau pateikiamas apytikslis duomenų rėmelis.

  gene hsap mmul mmus rnor cfam 1 ENSG00000208234 0 NA NA NA NA 2 ENSG00000199674 0 2 2 2 2 3 ENSG00000221622 0 NA NA NA NA 4 ENSG00000207604 0 NA NA 1 2 5 ENSG00000207431 0 NA NA NA NA 6 ENSG00000221312 0 1 2 3 2 

Iš esmės norėčiau gauti duomenų rėmelį, pvz., Toliau.

  gene hsap mmul mmus rnor cfam 2 ENSG00000199674 0 2 2 2 2 6 ENSG00000221312 0 1 2 3 2 

b) pateikite NA tik kai kuriuose stulpeliuose , todėl taip pat galiu gauti šį rezultatą:

  gene hsap mmul mmus rnor cfam 2 ENSG00000199674 0 2 2 2 2 4 ENSG00000207604 0 NA NA 1 2 6 ENSG00000221312 0 1 2 3 2 
662
01 февр. nustatė Benoit B. 01 vasaris 2011-02-01 14:52 '11 at 14:52 2011-02-01 14:52
@ 15 atsakymų

Taip pat patikrinkite complete.cases :

 > final[complete.cases(final), ] gene hsap mmul mmus rnor cfam 2 ENSG00000199674 0 2 2 2 2 6 ENSG00000221312 0 1 2 3 2 

na.omit geriausia ištrinti visus NA . complete.cases leidžia dalinius pasirinkimus, įskaitant tik tam tikras duomenų rėmo stulpelius:

 > final[complete.cases(final[ , 5:6]),] gene hsap mmul mmus rnor cfam 2 ENSG00000199674 0 2 2 2 2 4 ENSG00000207604 0 NA NA 1 2 6 ENSG00000221312 0 1 2 3 2 

Jūsų sprendimas gali neveikti. Jei is.na naudoti „ is.na , turite daryti kažką panašaus:

 > final[rowSums(is.na(final[ , 5:6])) == 0, ] gene hsap mmul mmus rnor cfam 2 ENSG00000199674 0 2 2 2 2 4 ENSG00000207604 0 NA NA 1 2 6 ENSG00000221312 0 1 2 3 2 

bet complete.cases naudojamų complete.cases daug suprantamesnis ir greitesnis.

841
01 февр. Atsakymą pateikė Joris Meys 01 vasaris. 2011-02-01 15:21 '11 prie 15:21 2011-02-01 15:21

Pabandykite na.omit(your.data.frame) . Kalbant apie antrąjį klausimą, pabandykite paskelbti jį kaip kitą klausimą (dėl aiškumo).

205
01 февр. Atsakymas duotas Roman Luštrik 01 vasario mėn. 2011-02-01 15:00 '11 15:00 val. 2011-02-01 15:00

Norėčiau patikrinti, ar eilutėse nėra NA:

 row.has.na <- apply(final, 1, function(x){any(is.na(x))}) 

Grąžina loginį vektorių su reikšmėmis, rodančiomis, ar eilutėje yra NA. Galite jį naudoti norėdami pamatyti, kiek eilučių reikia numesti:

 sum(row.has.na) 

ir galų gale juos nuleisti

 final.filtered <- final[!row.has.na,] 

Norėdami filtruoti eilutes su tam tikra NA dalimi, ji tampa šiek tiek sudėtingesnė (pavyzdžiui, galite taikyti „galutinį [, 5: 6]“ į „taikyti“). Paprastai Joris Meys sprendimas atrodo elegantiškesnis.

78
03 февр. atsakymas donshikin 03 vasaris 2011-02-03 00:58 '11 at 0:58 2011-02-03 00:58

Jei jums patinka vamzdžiai ( %>% ), tidyr new drop_na yra jūsų draugas:

 library(tidyr) df %>% drop_na() # gene hsap mmul mmus rnor cfam # 2 ENSG00000199674 0 2 2 2 2 # 6 ENSG00000221312 0 1 2 3 2 df %>% drop_na(rnor, cfam) # gene hsap mmul mmus rnor cfam # 2 ENSG00000199674 0 2 2 2 2 # 4 ENSG00000207604 0 NA NA 1 2 # 6 ENSG00000221312 0 1 2 3 2 
53
16 авг. atsakymas, kurį pateikė lukeA 16 rug . 2016-08-16 11:49 '16 at 11:49 2016-08-16 11:49

Kita galimybė, jei norite daugiau kontroliuoti, kaip eilutės laikomos negaliojančiomis, yra

 final <- final[!(is.na(final$rnor)) | !(is.na(rawdata$cfam)),] 

Naudojant tai, kas išdėstyta, tai yra:

  gene hsap mmul mmus rnor cfam 1 ENSG00000208234 0 NA NA NA 2 2 ENSG00000199674 0 2 2 2 2 3 ENSG00000221622 0 NA NA 2 NA 4 ENSG00000207604 0 NA NA 1 2 5 ENSG00000207431 0 NA NA NA NA 6 ENSG00000221312 0 1 2 3 2 

tampa:

  gene hsap mmul mmus rnor cfam 1 ENSG00000208234 0 NA NA NA 2 2 ENSG00000199674 0 2 2 2 2 3 ENSG00000221622 0 NA NA 2 NA 4 ENSG00000207604 0 NA NA 1 2 6 ENSG00000221312 0 1 2 3 2 

... kur išbraukiama tik 5 eilutė, nes ji yra vienintelė linija, kurioje yra NA, kaip ir „ rnor cfam . Tada loginė logika gali būti pakeista, kad ji atitiktų konkrečius reikalavimus.

36
05 нояб. atsakymas pateikiamas ten, kur tenka lapkričio 5 d. 2013-11-05 09:30 '13, 9:30 val. 2013-11-05 09:30

Jei norite valdyti kiekvienos eilutės NA skaičių, pabandykite šią funkciją. Daugeliui apklausų duomenų rinkinių per daug tuščių atsakymų į klausimus gali sugadinti rezultatus. Todėl jie ištrinami po tam tikros ribos. Ši funkcija leis jums pasirinkti, kiek NA, kurį eilutė gali turėti, prieš ištrindama:

 delete.na <- function(DF, n=0) { DF[rowSums(is.na(DF)) <= n,] } 

Pagal numatytuosius nustatymus ji pašalins visus NA:

 delete.na(final) gene hsap mmul mmus rnor cfam 2 ENSG00000199674 0 2 2 2 2 6 ENSG00000221312 0 1 2 3 2 

Arba nurodykite maksimalų leistiną leistinų NA skaičių:

 delete.na(final, 2) gene hsap mmul mmus rnor cfam 2 ENSG00000199674 0 2 2 2 2 4 ENSG00000207604 0 NA NA 1 2 6 ENSG00000221312 0 1 2 3 2 
31
26 мая '15 в 17:49 2015-05-26 17:49 Atsakymą pateikė Pierre Lafortune gegužės 26 d. 15, 17:49 2015-05-26 17:49

Tai grąžins eilutes, turinčias bent vieną vertę, išskyrus NA.

 final[rowSums(is.na(final))<length(final),] 

Tai grąžins eilutes, turinčias ne mažiau kaip dvi vertes, išskyrus NA.

 final[rowSums(is.na(final))<(length(final)-1),] 
14
19 сент. atsakymas duotas Leo 19 rugsėjo. 2014-09-19 15:36 '14 at 15:36 2014-09-19 15:36

Tam taip pat galime naudoti pogrupio funkciją.

 finalData<-subset(data,!(is.na(data["mmul"]) | is.na(data["rnor"]))) 

Tai suteiks tik tas linijas, kuriose NA ir mm, ir RNOR nėra

12
12 нояб. Atsakymą pateikė Ramya Ural , lapkričio 12 d. 2014-11-12 01:15 '14 ne 1:15 2014-11-12 01:15

Naudodami dplyr paketą, NA galime filtruoti taip:

 dplyr::filter(df, !is.na(columnname)) 
12
12 апр. Raminsu pateiktas atsakymas balandžio 12 d 2017-04-12 08:44 '17 ne 8:44 2017-04-12 08:44

Jei našumas yra prioritetas, naudokite data.table ir na.omit() su papildomais parametrais na.omit() cols= .

na.omit.data.table yra greičiausias mano bandymuose (žr. toliau), nesvarbu, ar tai yra visi stulpeliai ar pasirinktos stulpeliai (2 klausimo klausimo dalis).

Jei nenorite naudoti „ data.table , naudokite complete.cases() .

data.frame , complete.cases data.frame complete.cases greitesnės nei na.omit() arba dplyr::drop_na() . Pastaba: na.omit.data.frame nepalaiko na.omit.data.frame cols= .

Bandymo rezultatas

Toliau pateikiamas visų duomenų bazės (mėlynos), dplyr (rožinės) ir data.table (geltonos) metodų data.table arba trūkstamų stebėjimų parinkimas sąlyginiam duomenų rinkiniui, kuriame yra 1 milijonas stebėjimo 20 skaitmeninių kintamųjų, kurių nepriklausoma tikimybė yra 5%, ir pogrupis keturių kintamųjų 2 dalyje.

Rezultatai gali skirtis priklausomai nuo jūsų duomenų rinkinio ilgio, pločio ir retumo.

Žurnalo skalė y ašyje.

2019

16 февр. Atsakymas pateiktas C8H10N4O2 16 vasario 16 d. 2018-02-16 18:41 '18, 18:41 pm 2018-02-16 18:41

Dėl savo pirmojo klausimo turiu kodą, kuris yra patogus man atsikratyti visų NA. Dėkojame, kad @Gregor lengviau.

 final[!(rowSums(is.na(final))),] 

Antruoju klausimu šis kodas paprasčiausiai yra ankstesnio sprendimo skilimas.

 final[as.logical((rowSums(is.na(final))-5)),] 

Atkreipkite dėmesį, kad -5 yra jūsų stulpelių skaičius. Tai pašalins eilutes su visomis NA, nes eilutėsSumažina iki 5, o po atimties jie tampa nuliais. Šis laikas, kaip .logical, yra būtinas.

11
09 февр. Atsakymą pateikė LegitMe 09 vasaris. 2016-02-09 20:52 '16 at 8:52 pm 2016-02-09 20:52

Aš esu sintezatorius :). Čia aš sujungiau atsakymus į vieną funkciją:

 #' keep rows that have a certain number (range) of NAs anywhere/somewhere and delete others #' @param df a data frame #' @param col restrict to the columns where you would like to search for NA; eg, 3, c(3), 2:5, "place", c("place","age") #' \cr default is NULL, search for all columns #' @param n integer or vector, 0, c(3,5), number/range of NAs allowed. #' \cr If a number, the exact number of NAs kept #' \cr Range includes both ends 3<=n<=5 #' \cr Range could be -Inf, Inf #' @return returns a new df with rows that have NA(s) removed #' @export ez.na.keep = function(df, col=NULL, n=0){ if (!is.null(col)) { # R converts a single row/col to a vector if the parameter col has only one col # see https://radfordneal.wordpress.com/2008/08/20/design-flaws-in-r-2-%E2%80%94-dropped-dimensions/#comments df.temp = df[,col,drop=FALSE] } else { df.temp = df } if (length(n)==1){ if (n==0) { # simply call complete.cases which might be faster result = df[complete.cases(df.temp),] } else { # credit: http://stackoverflow.com/a/30461945/2292993 log <- apply(df.temp, 2, is.na) logindex <- apply(log, 1, function(x) sum(x) == n) result = df[logindex, ] } } if (length(n)==2){ min = n[1]; max = n[2] log <- apply(df.temp, 2, is.na) logindex <- apply(log, 1, function(x) {sum(x) >= min  sum(x) <= max}) result = df[logindex, ] } return(result) } 
8
03 февр. Atsakymas duotas Jerry T 03 vasaris. 2016-02-03 20:48 '16 at 8:48 pm 2016-02-03 20:48

Darant prielaidą, dat jūsų duomenų rėmas yra duomenų, tikėtiną rezultatą galima pasiekti naudojant

1. rowSums

 > dat[!rowSums((is.na(dat))),] gene hsap mmul mmus rnor cfam 2 ENSG00000199674 0 2 2 2 2 6 ENSG00000221312 0 1 2 3 2 

2. lapply

 > dat[!Reduce('|',lapply(dat,is.na)),] gene hsap mmul mmus rnor cfam 2 ENSG00000199674 0 2 2 2 2 6 ENSG00000221312 0 1 2 3 2 
5
15 марта '17 в 19:51 2017-03-15 19:51 atsakymas pateikiamas „ Prradep“ kovo 15 d. 17:17 19:51 2017-03-15 19:51
 delete.dirt <- function(DF, dart=c('NA')) { dirty_rows <- apply(DF, 1, function(r) !any(r %in% dart)) DF <- DF[dirty_rows, ] } mydata <- delete.dirt(mydata) 

Pirmiau nurodyta funkcija pašalina visas eilutes iš duomenų rėmelio, kuriame bet kurioje stulpelyje yra „NA“, ir grąžina gautus duomenis. Jei norite išbandyti kelias vertes, pvz., NA ir ? keisti dart=c('NA') funkcijos parametre dart=c('NA', '?')

1
23 февр. atsakymas pateikiamas 23 val 2018-02-23 01:19 '18 prie 1:19 2018-02-23 01:19

Manau, kad tokiu būdu tai galėtų būti labiau išspręsta.

  m <- matrix(1:25, ncol = 5) m[c(1, 6, 13, 25)] <- NA df <- data.frame(m) library(dplyr) df %>% filter_all(any_vars(is.na(.))) #> X1 X2 X3 X4 X5 #> 1 NA NA 11 16 21 #> 2 3 8 NA 18 23 #> 3 5 10 15 20 NA 
0
08 мая '18 в 23:35 2018-05-08 23:35 Atsakymą pateikė Joni Hoppen , gegužės 08-18 d., 23:35 2018-05-08 23:35