Tôi có một khung dữ liệu với một số cột số. Một số hàng có giá trị 0 nên được coi là null trong phân tích thống kê. Cách nhanh nhất để thay thế tất cả giá trị 0 thành NULL trong R là gì?
Tôi có một khung dữ liệu với một số cột số. Một số hàng có giá trị 0 nên được coi là null trong phân tích thống kê. Cách nhanh nhất để thay thế tất cả giá trị 0 thành NULL trong R là gì?
Câu trả lời:
Thay thế tất cả các số 0 thành NA:
df[df == 0] <- NA
Giải trình
1. Nó không phải là NULL
những gì bạn nên thay thế số không bằng. Như đã nói ?'NULL'
,
NULL đại diện cho đối tượng null trong R
đó là duy nhất và, tôi đoán, có thể được coi là đối tượng không chính xác và trống rỗng nhất. 1 Sau đó, nó trở nên không quá ngạc nhiên
data.frame(x = c(1, NULL, 2))
# x
# 1 1
# 2 2
Đó là, R không dành bất kỳ khoảng trống nào cho đối tượng null này. 2 Trong khi đó, nhìn vào ?'NA'
chúng ta thấy rằng
NA là hằng số logic có độ dài 1 chứa chỉ số giá trị bị thiếu. NA có thể được ép buộc với bất kỳ loại vectơ nào khác ngoại trừ nguyên.
Điều quan trọng, NA
có độ dài 1 để R dành một khoảng trống cho nó. Ví dụ,
data.frame(x = c(1, NA, 2))
# x
# 1 1
# 2 NA
# 3 2
Ngoài ra, cấu trúc khung dữ liệu yêu cầu tất cả các cột phải có cùng số lượng phần tử để không có "lỗ" (nghĩa là NULL
các giá trị).
Bây giờ bạn có thể thay thế số không bằng NULL
một khung dữ liệu theo nghĩa loại bỏ hoàn toàn tất cả các hàng chứa ít nhất một số không. Khi sử dụng, ví dụ như, var
, cov
, hoặc cor
, đó là thực sự tương đương với đầu thay thế zero với NA
và thiết lập giá trị của use
là "complete.obs"
. Thông thường, tuy nhiên, điều này là không thỏa đáng vì nó dẫn đến mất thêm thông tin.
2. Thay vì chạy một số loại vòng lặp, trong giải pháp tôi sử dụng df == 0
vector hóa. df == 0
trả về (thử nó) một ma trận có cùng kích thước df
với các mục TRUE
và FALSE
. Hơn nữa, chúng tôi cũng được phép truyền ma trận này cho tập hợp con [...]
(xem ?'['
). Cuối cùng, trong khi kết quả df[df == 0]
là hoàn toàn trực quan, nó có vẻ lạ df[df == 0] <- NA
mang lại hiệu quả mong muốn. Toán tử gán <-
thực sự không phải lúc nào cũng thông minh và không hoạt động theo cách này với một số đối tượng khác, nhưng nó làm như vậy với các khung dữ liệu; thấy ?'<-'
.
1 Tập hợp trống trong lý thuyết tập hợp cảm thấy bằng cách nào đó liên quan.
2 Một điểm tương đồng khác với lý thuyết tập hợp: tập hợp trống là tập hợp con của mọi tập hợp, nhưng chúng tôi không dành bất kỳ khoảng trống nào cho nó.
Hãy để tôi giả sử rằng data.frame của bạn là sự pha trộn của các kiểu dữ liệu khác nhau và không phải tất cả các cột cần phải được sửa đổi.
để sửa đổi chỉ các cột 12 thành 18 (trong tổng số 21), chỉ cần làm điều này
df[, 12:18][df[, 12:18] == 0] <- NA
Một cách khác mà không cần [<-
chức năng:
Khung dữ liệu mẫu dat
(được sao chép một cách đáng xấu hổ từ câu trả lời của @ Chase):
dat
x y
1 0 2
2 1 2
3 1 1
4 2 1
5 0 0
Số không có thể được thay thế NA
bằng is.na<-
chức năng:
is.na(dat) <- !dat
dat
x y
1 NA 2
2 1 2
3 1 1
4 2 1
5 NA NA
Vì ai đó đã yêu cầu phiên bản Data.Table của điều này và vì giải pháp data.frame đã cho không hoạt động với data.table, tôi sẽ cung cấp giải pháp bên dưới.
Về cơ bản, sử dụng :=
toán tử ->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
Bạn chỉ có thể thay thế 0
bằng NA
các trường số (nghĩa là loại trừ những thứ như các yếu tố), nhưng nó hoạt động trên cơ sở từng cột:
col[col == 0 & is.numeric(col)] <- NA
Với một chức năng, bạn có thể áp dụng điều này cho toàn bộ khung dữ liệu của mình:
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))
Mặc dù bạn có thể thay thế 1:5
bằng số lượng cột trong khung dữ liệu của mình hoặc bằng 1:ncol(df)
.
1:5
với 1:ncol(df)
lúc kết thúc. Tôi không muốn làm cho phương trình quá phức tạp hoặc khó đọc.
1:5
số cột bạn muốn thay đổi, 12:15
nhưng nếu bạn muốn xác nhận rằng nó sẽ chỉ ảnh hưởng đến các cột số thì chỉ cần bọc dòng thứ hai của hàm trong câu lệnh if, như sau : if (is.numeric(col)) { col[col == -1 & is.numeric(col)] <- NA }
.