ลบค่า NA ออกจากเวกเตอร์


191

ฉันมีเวกเตอร์ขนาดใหญ่ที่มีค่าอยู่สองสามNAค่าและฉันพยายามหาค่าสูงสุดในเวกเตอร์นั้น (เวกเตอร์นั้นเป็นตัวเลขทั้งหมด) แต่ฉันทำไม่ได้เพราะNAค่า

ฉันจะลบNAค่าต่างๆเพื่อให้สามารถคำนวณค่าสูงสุดได้อย่างไร

คำตอบ:


265

พยายามที่?maxคุณจะเห็นว่ามันจริงมีอาร์กิวเมนต์ชุดโดยค่าเริ่มต้นna.rm = FALSE(นั่นคือเริ่มต้นที่พบบ่อยสำหรับฟังก์ชั่น R อื่น ๆ อีกมากมายรวมทั้งsum(), mean()ฯลฯ )

การตั้งค่าna.rm=TRUEทำได้เพียงแค่สิ่งที่คุณต้องการ:

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

หากคุณต้องการที่จะลบทั้งหมดของNAใช้สำนวนนี้แทน:

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

หมายเหตุสุดท้าย: ฟังก์ชั่นอื่น ๆ (เช่นtable(), lm()และsort()) มีNAอาร์กิวเมนต์ที่เกี่ยวข้องซึ่งใช้ชื่อต่างกัน (และเสนอตัวเลือกต่าง ๆ ) ดังนั้นหากNAคุณทำให้เกิดปัญหาในการเรียกใช้ฟังก์ชันมันก็คุ้มค่าที่จะตรวจสอบวิธีแก้ปัญหาในตัวระหว่างข้อโต้แย้งของฟังก์ชัน ฉันพบว่ามักจะมีอยู่แล้วที่นั่น


นี่เป็นความคิดที่แย่มาก มันล้มเหลวและให้-InfสำหรับdNA ทั้งหมด
user3932000

@ user3932000 เพื่อให้ชัดเจนสำหรับผู้อื่นการร้องเรียนของคุณเป็นเรื่องเกี่ยวกับการทำงานของฟังก์ชัน R พื้นฐานmax()(เช่นเมื่อดำเนินการmax(c(NA, NA)) ส่วนตัวแล้วฉันคิดว่าพฤติกรรมของมันสมเหตุสมผล ฉันคาดหวังว่ามันจะถูกสร้างขึ้นแบบนั้นเพื่อให้คุณได้รับผลลัพธ์ที่คาดหวังเมื่อทำสิ่งต่าง ๆ เช่นa <- c(NA, NA); b <- 1:4; max(c(max(a, na.rm = TRUE), max(b, na.rm = TRUE)))
Josh O'Brien

@ user3932000 ค่อนข้างสัมผัสซึ่งเป็นหนึ่งในจุดแข็งหลายอาร์เอสเป็นแพลตฟอร์มการวิเคราะห์ข้อมูลคือการจัดการความซับซ้อนของข้อมูลที่หายไปจากผลของการมากคิดระวังในส่วนของผู้เขียนของตน (หากคุณสนใจในหัวข้อโปรดดูที่นี่สำหรับการสนทนาที่ดีของปัญหาที่เกี่ยวข้องจากมุมมองของโปรแกรมเมอร์ที่มีส่วนร่วมในการรวมNAสิ่งอำนวยความสะดวกR-like- handling ในแพ็คเกจNumPy ที่ยอดเยี่ยมของ Python )
Josh O'Brien

@ user3932000: คำตอบนั้นไม่ดีจริงเหรอ? คุณจะพิจารณาถึงสิ่งที่สูงสุดของการตั้งค่าเป็นโมฆะ?
หน้าผา AB

@CliffAB มันไม่มีค่าสูงสุด คุณสามารถกำหนดจำนวนสูงสุดเป็น-∞ (และขั้นต่ำเป็น + ∞) แต่ไม่ต้องการหรือใช้งานง่ายเสมอไป นอกจากนี้เมื่อคุณลบNAs ทั้งหมดออกจากเวกเตอร์ของNAs คุณจะคาดหวังว่าเวกเตอร์เปล่าไม่ใช่-∞
user3932000

94

na.omitฟังก์ชั่นเป็นสิ่งที่มากของการปฏิบัติถดถอยใช้ภายใน:

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

20

?maxแสดงให้คุณเห็นว่ามีพารามิเตอร์พิเศษna.rmที่คุณสามารถตั้งค่าTRUEได้

นอกจากนั้นหากคุณต้องการที่จะลบออกจริงๆNAเพียงใช้สิ่งที่ชอบ:

myvec[!is.na(myvec)]

3
ฉันคิดว่านี่ดีที่สุด na.rm และ na.omit เพิ่มขยะไปที่เอาต์พุต
MadmanLee

ยกเว้นna.omitยังมีวิธีการดาต้าเฟรมดังนั้นจึงเป็นเรื่องทั่วไปมากขึ้น
IRTFM


14

ในกรณีที่มีคนใหม่ R ต้องการคำตอบที่ง่ายสำหรับคำถามเดิม

ฉันจะลบค่า NA ออกจากเวกเตอร์ได้อย่างไร

นี่มันคือ:

สมมติว่าคุณมีเวกเตอร์fooดังต่อไปนี้:

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

การวิ่งlength(foo)ให้ 22

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

length(nona_foo) คือ 21 เนื่องจากค่า NA ถูกลบออก

อย่าลืมis.na(foo)ส่งคืนเมทริกซ์บูลีนดังนั้นการสร้างดัชนีfooโดยตรงกันข้ามกับค่านี้จะให้องค์ประกอบทั้งหมดที่ไม่ใช่ NA


13

ใช้discardจากpurrr (ใช้ได้กับรายการและเวกเตอร์)

discard(v, is.na) 

ประโยชน์คือใช้งานง่าย หรือใช้ฟังก์ชันการตั้งค่าย่อยในตัว[:

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

โปรดทราบว่าna.omitไม่สามารถใช้ได้กับรายการ:

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

$b
[1] 2

$c
[1] NA

1

ฉันวิ่งมาตรฐานอย่างรวดเร็วเปรียบเทียบทั้งสองbaseวิธีการและปรากฎว่าจะเร็วกว่าx[!is.na(x)] na.omitผู้ใช้qwrแนะนำฉันลองpurrr::dicardด้วย - สิ่งนี้กลายเป็นช้าลงอย่างมาก (แม้ว่าฉันจะแสดงความคิดเห็นอย่างมีความสุขกับการติดตั้งและทดสอบ!)

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

สำหรับการอ้างอิงต่อไปนี้เป็นการทดสอบแบบดั้งเดิมของ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

คุณควรลองpurrr:discard
qwr
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.