ฉันมี dataframe พร้อมคอลัมน์ตัวเลขบางตัว บางแถวมีค่า 0 ซึ่งควรพิจารณาว่าเป็นโมฆะในการวิเคราะห์ทางสถิติ วิธีที่เร็วที่สุดในการแทนที่ค่า 0 ทั้งหมดเป็น NULL ใน R คืออะไร
ฉันมี dataframe พร้อมคอลัมน์ตัวเลขบางตัว บางแถวมีค่า 0 ซึ่งควรพิจารณาว่าเป็นโมฆะในการวิเคราะห์ทางสถิติ วิธีที่เร็วที่สุดในการแทนที่ค่า 0 ทั้งหมดเป็น NULL ใน R คืออะไร
คำตอบ:
แทนที่ศูนย์ทั้งหมดเป็น NA:
df[df == 0] <- NA
คำอธิบาย
1.ไม่ใช่NULLสิ่งที่คุณควรต้องการแทนที่ศูนย์ด้วย ตามที่กล่าวใน?'NULL',
NULL แสดงถึงวัตถุ null ใน R
ซึ่งเป็นเอกลักษณ์และฉันคิดว่าสามารถมองได้ว่าเป็นวัตถุที่ไม่รู้เรื่องและว่างเปล่าที่สุด 1จากนั้นไม่น่าแปลกใจเลยที่
data.frame(x = c(1, NULL, 2))
# x
# 1 1
# 2 2
นั่นคือ R ไม่ได้จองพื้นที่ใด ๆ สำหรับวัตถุ null นี้ 2ในขณะเดียวกันดูที่?'NA'เราเห็นว่า
NA เป็นค่าคงที่เชิงตรรกะของความยาว 1 ซึ่งมีตัวบ่งชี้ค่าที่ขาดหายไป NA สามารถ coerced กับเวกเตอร์ชนิดอื่นยกเว้น raw
ที่สำคัญNAมีความยาว 1 เพื่อให้ R สงวนพื้นที่ไว้ให้ เช่น,
data.frame(x = c(1, NA, 2))
# x
# 1 1
# 2 NA
# 3 2
นอกจากนี้โครงสร้างเฟรมข้อมูลต้องการคอลัมน์ทั้งหมดเพื่อให้มีองค์ประกอบจำนวนเดียวกันเพื่อที่จะไม่มี "รู" (เช่นNULLค่า)
ตอนนี้คุณสามารถแทนที่ศูนย์ด้วยNULLในกรอบข้อมูลในแง่ของการลบแถวทั้งหมดที่มีอย่างน้อยหนึ่งศูนย์ เมื่อใช้เช่นvar, covหรือcorที่เป็นจริงเทียบเท่ากับครั้งแรกของการเปลี่ยนเลขด้วยNAและการตั้งค่าของการเป็นuse "complete.obs"อย่างไรก็ตามโดยทั่วไปสิ่งนี้ไม่เป็นที่น่าพอใจเนื่องจากนำไปสู่การสูญเสียข้อมูลเพิ่มเติม
2.แทนที่จะใช้ลูปบางประเภทในโซลูชันฉันใช้df == 0vectorization df == 0ผลตอบแทน (ลอง) เมทริกซ์ที่มีขนาดเดียวกับdfที่มีรายการและTRUE FALSEนอกจากนี้เรายังได้รับอนุญาตให้ส่งเมทริกซ์นี้ไปยังการตั้งค่าย่อย[...](ดู?'[') สุดท้ายในขณะที่ผลลัพธ์ของการdf[df == 0]ใช้งานง่ายอย่างสมบูรณ์แบบมันอาจดูแปลกที่df[df == 0] <- NAให้ผลที่ต้องการ ผู้ประกอบการที่ได้รับมอบหมาย<-ไม่ได้ฉลาดเสมอไปและไม่สามารถใช้วิธีนี้กับวัตถุอื่น ๆ ได้ แต่จะทำเช่นนั้นกับ data frames เห็น?'<-'ไหม
1เซตว่างในทฤษฎีเซตรู้สึกว่าเกี่ยวข้องกัน
2ความคล้ายคลึงกันอื่น ๆ กับทฤษฎีเซต: เซตว่างเป็นเซตย่อยของทุกเซต แต่เราจะไม่สงวนพื้นที่ใด ๆ ไว้
ให้ฉันสมมติว่า data.frame ของคุณเป็นการผสมผสานของประเภทข้อมูลที่แตกต่างกันและไม่จำเป็นต้องแก้ไขคอลัมน์ทั้งหมด
หากต้องการแก้ไขเฉพาะคอลัมน์ 12 ถึง 18 (จากทั้งหมด 21) ให้ทำเช่นนี้
df[, 12:18][df[, 12:18] == 0] <- NA
ทางเลือกอื่นที่ไม่มี[<-ฟังก์ชัน:
กรอบข้อมูลตัวอย่างdat(คัดลอกมาจากคำตอบของ @ Chase):
dat
x y
1 0 2
2 1 2
3 1 1
4 2 1
5 0 0
เลขสามารถถูกแทนที่ด้วยNAโดยis.na<-ฟังก์ชั่น:
is.na(dat) <- !dat
dat
x y
1 NA 2
2 1 2
3 1 1
4 2 1
5 NA NA
dplyr::na_if() เป็นตัวเลือก:
library(dplyr)
df <- data_frame(col1 = c(1, 2, 3, 0),
col2 = c(0, 2, 3, 4),
col3 = c(1, 0, 3, 0),
col4 = c('a', 'b', 'c', 'd'))
na_if(df, 0)
# A tibble: 4 x 4
col1 col2 col3 col4
<dbl> <dbl> <dbl> <chr>
1 1 NA 1 a
2 2 2 NA b
3 3 3 3 c
4 NA 4 NA d
#Sample data
set.seed(1)
dat <- data.frame(x = sample(0:2, 5, TRUE), y = sample(0:2, 5, TRUE))
#-----
x y
1 0 2
2 1 2
3 1 1
4 2 1
5 0 0
#replace zeros with NA
dat[dat==0] <- NA
#-----
x y
1 NA 2
2 1 2
3 1 1
4 2 1
5 NA NA
เนื่องจากมีคนถามหา Data.Table เวอร์ชันนี้และเนื่องจากโซลูชัน data.frame ที่กำหนดไม่สามารถใช้งานกับ data.table ได้ฉันจึงนำเสนอโซลูชันด้านล่าง
โดยทั่วไปให้ใช้:=โอเปอเรเตอร์ ->DT[x == 0, x := NA]
library("data.table")
status = as.data.table(occupationalStatus)
head(status, 10)
origin destination N
1: 1 1 50
2: 2 1 16
3: 3 1 12
4: 4 1 11
5: 5 1 2
6: 6 1 12
7: 7 1 0
8: 8 1 0
9: 1 2 19
10: 2 2 40
status[N == 0, N := NA]
head(status, 10)
origin destination N
1: 1 1 50
2: 2 1 16
3: 3 1 12
4: 4 1 11
5: 5 1 2
6: 6 1 12
7: 7 1 NA
8: 8 1 NA
9: 1 2 19
10: 2 2 40
คุณสามารถแทนที่ได้0ด้วยNAในเขตข้อมูลตัวเลขเท่านั้น (เช่นไม่รวมสิ่งต่าง ๆ เช่นปัจจัย) แต่ทำงานได้ในแต่ละคอลัมน์:
col[col == 0 & is.numeric(col)] <- NA
ด้วยฟังก์ชั่นคุณสามารถใช้สิ่งนี้กับกรอบข้อมูลทั้งหมดของคุณ:
changetoNA <- function(colnum,df) {
col <- df[,colnum]
if (is.numeric(col)) { #edit: verifying column is numeric
col[col == -1 & is.numeric(col)] <- NA
}
return(col)
}
df <- data.frame(sapply(1:5, changetoNA, df))
แม้ว่าคุณจะสามารถแทนที่ด้วยหมายเลขของคอลัมน์ในกรอบข้อมูลของคุณหรือ1:51:ncol(df)
1:5ด้วย1:ncol(df)ในตอนท้าย ฉันไม่ต้องการสร้างสมการที่ซับซ้อนเกินไปหรืออ่านยาก
1:5ไปยังหมายเลขคอลัมน์ที่คุณต้องการเปลี่ยนแปลงเช่นแต่ถ้าคุณอยากจะยืนยันว่ามันจะมีผลเฉพาะคอลัมน์ที่เป็นตัวเลขแล้วก็ตัดบรรทัดที่สองของฟังก์ชั่นในงบถ้าเช่นนี้12:15 if (is.numeric(col)) { col[col == -1 & is.numeric(col)] <- NA }
ในกรณีที่ใครมาถึงที่นี่ผ่านทาง google มองหาสิ่งที่ตรงกันข้าม (เช่นวิธีการแทนที่ NAs ทั้งหมดใน data.frame ด้วย 0) คำตอบคือ
df[is.na(df)] <- 0
หรือ
ใช้ dplyr / tidyverse
library(dplyr)
mtcars %>% replace(is.na(.), 0)