ฉันมี 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 == 0
vectorization 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:5
1: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)