ชุดย่อยของแถวที่มีค่า NA (ไม่มี) ในคอลัมน์ที่เลือกของกรอบข้อมูล


97

เรามีกรอบข้อมูลจากไฟล์ CSV กรอบข้อมูลDFมีคอลัมน์ที่มีค่าที่สังเกตได้และคอลัมน์ ( VaR2) ที่มีวันที่ที่ทำการวัด หากไม่ได้บันทึกวันที่ไว้ไฟล์ CSV จะมีค่าNAสำหรับข้อมูลที่ขาดหายไป

Var1  Var2 
10   2010/01/01
20   NA
30   2010/03/01

เราต้องการใช้คำสั่งย่อยเพื่อกำหนดกรอบข้อมูลใหม่new_DFเพื่อให้มีเฉพาะแถวที่มีNA'ค่าจากคอลัมน์ ( VaR2) ในตัวอย่างที่ระบุจะมีเฉพาะแถวที่ 2 DFเท่านั้น

คำสั่ง

new_DF<-subset(DF,DF$Var2=="NA") 

ไม่ทำงานเฟรมข้อมูลผลลัพธ์ไม่มีรายการแถว

หากในไฟล์ CSV เดิมราคาNAจะมีการแลกเปลี่ยนกับ คำสั่งเดียวกันผลิตผลลัพธ์ที่ต้องการ:NULLnew_DF<-subset(DF,DF$Var2=="NULL")

ฉันจะทำให้วิธีนี้ใช้งานได้อย่างไรหากสำหรับสตริงอักขระมีการระบุค่าNAไว้ในไฟล์ CSV ดั้งเดิม

คำตอบ:


151

อย่าใช้ == 'NA' เพื่อทดสอบค่าที่ขาดหายไป ใช้is.na()แทน สิ่งนี้ควรทำ:

new_DF <- DF[rowSums(is.na(DF)) > 0,]

หรือในกรณีที่คุณต้องการตรวจสอบคอลัมน์ใดคอลัมน์หนึ่งคุณสามารถใช้

new_DF <- DF[is.na(DF$Var),]

ในกรณีที่คุณมีค่าอักขระ NA ให้รันก่อน

Df[Df=='NA'] <- NA

เพื่อแทนที่ด้วยค่าที่ขาดหายไป


2
ขอบคุณสำหรับคำตอบที่รวดเร็วของคุณ เนื่องจากการส่งมอบข้อมูลแบบ csv 'NA' เป็นค่าอักขระและคำสั่งที่สองของคุณอาจมีประโยชน์มาก คุณสามารถชี้แจงคำแถลงแรกของคุณได้หรือไม่? การใช้ rowSums () ไม่ชัดเจนสำหรับฉันเนื่องจากฉันจะตรวจสอบเฉพาะคอลัมน์ใดคอลัมน์หนึ่งเท่านั้น (มีคอลัมน์มากมาย) ถ้าคอลัมน์นั้น (ในตัวอย่างจะเป็นคอลัมน์ Var2) มีสตริงอักขระ 'NA' (ฉันจะแทนที่ด้วยคำสั่งที่สองของคุณ) ฉันต้องการเลือกทั้งแถวเพื่อเป็นส่วนหนึ่งของ data frame ใหม่ .
John

@ จอห์น: ปรับปรุงแล้ว ประเด็นคือการใช้คือผมตีความผิดคุณต้องการตรวจสอบตัวแปรทั้งหมด
Joris Meys

3
ควรจะเป็นnew_DF <- DF[is.na(DF$Var),]เช่นมี(วงเล็บเสริมหลังจากDF[?
PatrickT

39

NA เป็นค่าพิเศษใน R อย่าผสมค่า NA กับสตริง "NA" ขึ้นอยู่กับวิธีการนำเข้าข้อมูลเซลล์ "NA" และ "NULL" ของคุณอาจเป็นประเภทต่างๆ (ลักษณะการทำงานเริ่มต้นคือการแปลงสตริง "NA" เป็นค่า NA และปล่อยให้สตริง "NULL" ตามที่เป็นอยู่)

หากใช้ read.table () หรือ read.csv () คุณควรพิจารณาอาร์กิวเมนต์ "na.strings" เพื่อทำการอิมพอร์ตข้อมูลที่สะอาดและใช้ได้กับค่า R NA จริงเสมอ

ตัวอย่างการทำงานในเซลล์ "NULL" และ "NA" ทั้งสองกรณี:

DF <- read.csv("file.csv", na.strings=c("NA", "NULL"))
new_DF <- subset(DF, is.na(DF$Var2))

1
ขอบคุณสำหรับคำตอบ. ถ้าฉันเข้าใจถูกต้องคำสั่งแรกจะทำเช่นเดียวกับ Df [Df == 'NA'] <- NA ในตัวอย่างของ Joris? ความแตกต่าง (เล็ก ๆ น้อย ๆ ) ก็คือว่ามันจะเสร็จสิ้นในสถิติของคุณในตอนแรกเมื่อสร้าง data frame (นี่เป็นวิธีการเขียนโปรแกรมที่สะอาดมากและฉันก็ชอบมัน)
John

ตรง Joris แนะนำให้แทนที่สตริง "NA" ด้วยค่า NA ด้วยตนเองที่นี่ฉันแนะนำให้ใช้คุณสมบัติ "na.strings" ของ read.table () เพื่อให้บรรลุวัตถุประสงค์เดียวกันเท่านั้น
maressyl

คำตอบของ Joris เป็นวิธีที่ "ต้องการ" ในการบรรลุความสำเร็จนี้ (หากคุณกำลังเขียนสิ่งนี้เป็นสคริปต์) ดู: stackoverflow.com/questions/9860090/…
Jonathan

@ โจนาธาน: สองแนวคิดที่แตกต่างกันที่นี่หัวข้อที่คุณอ้างถึงกล่าวว่า "[" ควรจะเป็น "เซตย่อย" แต่เรากำลังพูดถึงอาร์กิวเมนต์ "na.strings" ใน read.table () ชุดย่อยของฉันอยู่ที่นี่เพื่อให้เห็นภาพเท่านั้น ผลกระทบ.
maressyl


13
new_data <- data %>% filter_all(any_vars(is.na(.))) 

สิ่งนี้ควรสร้าง data frame ใหม่ ( new_data) โดยมีเฉพาะค่าที่ขาดหายไปเท่านั้น

ทำงานได้ดีที่สุดในการติดตามค่าที่คุณอาจทิ้งในภายหลังเนื่องจากมีบางคอลัมน์ที่ขาดการสังเกต (NA)


3

ลองเปลี่ยนสิ่งนี้:

new_DF<-dplyr::filter(DF,is.na(Var2)) 

คุณช่วยอธิบายได้ไหมว่าเหตุใดจึงได้ผลสิ่งนี้ทำอะไร ฯลฯ
csilk

new_DF <-dplyr :: filter (DF, is.na (Var2)) โดยทั่วไปจะใช้ฟังก์ชั่นตัวกรองของแพ็คเกจ dplyr และกรองการสังเกตใด ๆ ในคอลัมน์ Var2 ซึ่งเป็นไปตามเงื่อนไขนั่นคือพวกเขาเลือกการสังเกตทั้งหมดด้วย NA
drhnis

1
แสดงเพิ่มเติมอย่างเป็นหลังDF %>% filter(is.na(Var2)) library(dplyr)
โจ

-1

พิมพ์แถวทั้งหมดด้วยข้อมูล NA:

tmp <- data.frame(c(1,2,3),c(4,NA,5));
tmp[round(which(is.na(tmp))/ncol(tmp)),]

@ ZheyuanLi หากคุณไม่ชอบคำตอบเพียงแค่ลงคะแนน การแก้ไขคำตอบเพื่อแนะนำการตั้งค่าสถานะไม่ใช่การดำเนินการที่เหมาะสม แสดงความคิดเห็นหากคุณรู้สึกว่าจำเป็นต้องทำ
Manfred Radlwimmer
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.