Hapus nilai-nilai NA dari vektor

191

Saya memiliki vektor besar yang memiliki beberapa NAnilai, dan saya mencoba untuk menemukan nilai maks dalam vektor tersebut (vektor adalah semua angka), tetapi saya tidak dapat melakukan ini karena NAnilainya.

Bagaimana saya bisa menghapus NAnilai sehingga saya bisa menghitung maks?

CodeGuy
sumber

Jawaban:

265

Mencoba ?max, Anda akan melihat bahwa itu sebenarnya memiliki na.rm =argumen, ditetapkan secara default ke FALSE. (Itu default umum bagi banyak fungsi R lainnya, termasuk sum(), mean(), dll)

Pengaturan na.rm=TRUEtidak hanya apa yang Anda minta:

d <- c(1, 100, NA, 10)
max(d, na.rm=TRUE)

Jika Anda ingin menghapus semua NA, gunakan idiom ini sebagai gantinya:

d <- d[!is.na(d)]

Catatan terakhir: Fungsi lain (misalnya table(),, lm()dan sort()) memiliki NAargumen yang terkait yang menggunakan nama yang berbeda (dan menawarkan opsi yang berbeda). Jadi, jika NAAnda mengalami masalah dalam panggilan fungsi, ada baiknya memeriksa solusi bawaan di antara argumen fungsi. Saya telah menemukan biasanya sudah ada di sana.

Josh O'Brien
sumber
Ini ide yang sangat buruk. Gagal dan memberi -Infuntuk dsemua NAs.
user3932000
@ user3932000 Hanya untuk memperjelas bagi orang lain, keluhan Anda sebenarnya tentang bagaimana fungsi dasar R max()berperilaku (seperti, misalnya, ketika melakukan max(c(NA, NA)). Secara pribadi, saya pikir perilakunya masuk akal; Saya berharap itu dibangun seperti itu sehingga Anda mendapatkan hasil yang diharapkan ketika melakukan hal-hal sepertia <- c(NA, NA); b <- 1:4; max(c(max(a, na.rm = TRUE), max(b, na.rm = TRUE)))
Josh O'Brien
@ user3932000 Agak aneh, salah satu dari banyak kekuatan R sebagai platform analisis data adalah penanganannya yang canggih terhadap data yang hilang, hasil dari banyak pemikiran yang cermat dari pihak penulisnya. (Jika Anda tertarik pada subjek, lihat di sini untuk diskusi yang baik tentang beberapa masalah yang terlibat, dari sudut pandang programmer yang terlibat dalam menggabungkan NAfasilitas penanganan -R seperti dalam paket NumPy Python yang sangat baik .)
Josh O'Brien
@ user3932000: apakah jawaban itu benar-benar buruk? Apa yang Anda anggap maksimum dari set nol?
Cliff AB
@CliffAB Tidak maksimal. Anda dapat menetapkan maks menjadi -∞ (dan min menjadi + ∞), tetapi itu tidak selalu diinginkan atau intuitif. Juga, ketika Anda menghapus semua NAs dari vektor NAs, Anda akan mengharapkan vektor kosong, bukan -∞.
user3932000
94

The na.omitfungsi yang banyak rutinitas regresi menggunakan internal:

vec <- 1:1000
vec[runif(200, 1, 1000)] <- NA
max(vec)
#[1] NA
max( na.omit(vec) )
#[1] 1000
IRTFM
sumber
20

?maxmenunjukkan kepada Anda bahwa ada parameter tambahan na.rmyang dapat Anda atur TRUE.

Selain itu, jika Anda benar - benar ingin menghapusnya NA, cukup gunakan sesuatu seperti:

myvec[!is.na(myvec)]
Nick Sabbe
sumber
3
Saya pikir ini yang terbaik. na.rm dan na.omit menambahkan sedikit sampah ke output.
MadmanLee
Kecuali na.omitjuga memiliki metode dataframe, jadi lebih umum.
IRTFM
15

Anda bisa menelepon max(vector, na.rm = TRUE). Secara umum, Anda dapat menggunakan na.omit()fungsi ini.

Michael Hoffman
sumber
14

Untuk berjaga-jaga jika seseorang yang baru mengenal R ingin jawaban yang disederhanakan untuk pertanyaan aslinya

Bagaimana saya bisa menghapus nilai-nilai NA dari vektor?

Ini dia:

Asumsikan Anda memiliki vektor foosebagai berikut:

foo = c(1:10, NA, 20:30)

lari length(foo)memberi 22.

nona_foo = foo[!is.na(foo)]

length(nona_foo) adalah 21, karena nilai-nilai NA telah dihapus.

Ingatlah is.na(foo)mengembalikan matriks boolean, jadi pengindeksan foodengan kebalikan dari nilai ini akan memberi Anda semua elemen yang bukan NA.

Scott C Wilson
sumber
13

Gunakan discarddari purrr (berfungsi dengan daftar dan vektor).

discard(v, is.na) 

Keuntungannya adalah mudah menggunakan pipa; sebagai alternatif, gunakan fungsi pengesahan bawaan [:

v %>% discard(is.na)
v %>% `[`(!is.na(.))

Catatan yang na.omittidak berfungsi pada daftar:

> x <- list(a=1, b=2, c=NA)
> na.omit(x)
$a
[1] 1

$b
[1] 2

$c
[1] NA
qwr
sumber
2

Saya berlari patokan cepat membandingkan dua basependekatan dan ternyata x[!is.na(x)]lebih cepat daripada na.omit. Pengguna qwrmenyarankan agar saya mencoba purrr::dicardjuga - ini ternyata jauh lebih lambat (meskipun saya akan dengan senang hati berkomentar tentang implementasi & tes saya!)

microbenchmark::microbenchmark(
  purrr::map(airquality,function(x) {x[!is.na(x)]}), 
  purrr::map(airquality,na.omit),
  purrr::map(airquality, ~purrr::discard(.x, .p = is.na)),
  times = 1e6)

Unit: microseconds
                                                     expr    min     lq      mean median      uq       max neval cld
 purrr::map(airquality, function(x) {     x[!is.na(x)] })   66.8   75.9  130.5643   86.2  131.80  541125.5 1e+06 a  
                          purrr::map(airquality, na.omit)   95.7  107.4  185.5108  129.3  190.50  534795.5 1e+06  b 
  purrr::map(airquality, ~purrr::discard(.x, .p = is.na)) 3391.7 3648.6 5615.8965 4079.7 6486.45 1121975.4 1e+06   c

Untuk referensi, inilah tes asli x[!is.na(x)]vs na.omit:

microbenchmark::microbenchmark(
    purrr::map(airquality,function(x) {x[!is.na(x)]}), 
    purrr::map(airquality,na.omit), 
    times = 1000000)


Unit: microseconds
                                              expr  min   lq      mean median    uq      max neval cld
 map(airquality, function(x) {     x[!is.na(x)] }) 53.0 56.6  86.48231   58.1  64.8 414195.2 1e+06  a 
                          map(airquality, na.omit) 85.3 90.4 134.49964   92.5 104.9 348352.8 1e+06   b
jsavn
sumber
Anda harus mencobapurrr:discard
qwr