Saya memiliki kerangka data dengan beberapa kolom numerik. Beberapa baris memiliki nilai 0 yang harus dianggap nol dalam analisis statistik. Apa cara tercepat untuk mengganti semua nilai 0 ke NULL dalam R?
Saya memiliki kerangka data dengan beberapa kolom numerik. Beberapa baris memiliki nilai 0 yang harus dianggap nol dalam analisis statistik. Apa cara tercepat untuk mengganti semua nilai 0 ke NULL dalam R?
Jawaban:
Mengganti semua nol ke NA:
df[df == 0] <- NA
Penjelasan
1. Bukan NULL
apa yang Anda ingin ganti dengan nol. Seperti yang tertulis di ?'NULL'
,
NULL mewakili objek nol di R
yang unik dan, saya kira, dapat dilihat sebagai objek yang paling tidak informatif dan kosong. 1 Maka tidak begitu mengejutkan
data.frame(x = c(1, NULL, 2))
# x
# 1 1
# 2 2
Artinya, R tidak menyediakan ruang untuk objek nol ini. 2 Sementara itu, melihat ?'NA'
kita melihat itu
NA adalah konstanta logis dengan panjang 1 yang berisi indikator nilai yang hilang. NA dapat dipaksakan untuk jenis vektor lainnya kecuali mentah.
Yang penting, NA
adalah panjang 1 sehingga R menyediakan ruang untuk itu. Misalnya,
data.frame(x = c(1, NA, 2))
# x
# 1 1
# 2 NA
# 3 2
Selain itu, struktur bingkai data mengharuskan semua kolom memiliki jumlah elemen yang sama sehingga tidak ada "lubang" (yaitu, NULL
nilai).
Sekarang Anda bisa mengganti nol dengan NULL
dalam bingkai data dalam arti sepenuhnya menghapus semua baris yang mengandung setidaknya satu nol. Bila menggunakan, misalnya, var
, cov
, atau cor
, yang benar-benar setara dengan pertama menggantikan nol dengan NA
dan menetapkan nilai use
sebagai "complete.obs"
. Namun, biasanya, ini tidak memuaskan karena menyebabkan hilangnya informasi tambahan.
2. Alih-alih menjalankan semacam loop, dalam solusi saya menggunakan df == 0
vektorisasi. df == 0
mengembalikan (coba) matriks dengan ukuran yang sama dengan df
, dengan entri TRUE
dan FALSE
. Lebih lanjut, kami juga diizinkan untuk meneruskan matriks ini ke subset [...]
(lihat ?'['
). Terakhir, sementara hasil dari df[df == 0]
intuisi sempurna, mungkin tampak aneh yang df[df == 0] <- NA
memberikan efek yang diinginkan. Operator penugasan <-
memang tidak selalu begitu pintar dan tidak bekerja dengan cara ini dengan beberapa objek lain, tetapi ia melakukannya dengan bingkai data; lihat ?'<-'
.
1 Himpunan kosong dalam teori himpunan terasa entah bagaimana terkait.
2 Kesamaan lain dengan teori himpunan: himpunan kosong adalah himpunan bagian dari setiap himpunan, tetapi kami tidak menyediakan ruang untuk itu.
Biarkan saya berasumsi bahwa data.frame Anda adalah campuran dari tipe data yang berbeda dan tidak semua kolom perlu dimodifikasi.
untuk memodifikasi hanya kolom 12 hingga 18 (dari total 21), lakukan saja ini
df[, 12:18][df[, 12:18] == 0] <- NA
Cara alternatif tanpa [<-
fungsi:
Kerangka data sampel dat
(disalin tanpa malu-malu dari jawaban @ Chase):
dat
x y
1 0 2
2 1 2
3 1 1
4 2 1
5 0 0
Nol bisa diganti dengan NA
dengan is.na<-
fungsi:
is.na(dat) <- !dat
dat
x y
1 NA 2
2 1 2
3 1 1
4 2 1
5 NA NA
Karena seseorang meminta versi Data.Table ini, dan karena solusi data.frame yang diberikan tidak bekerja dengan data.table, saya memberikan solusi di bawah ini.
Pada dasarnya, gunakan :=
operator ->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
Anda dapat mengganti 0
dengan NA
hanya dalam bidang numerik (yaitu mengecualikan hal-hal seperti faktor), tetapi berfungsi berdasarkan kolom-demi-kolom:
col[col == 0 & is.numeric(col)] <- NA
Dengan suatu fungsi, Anda dapat menerapkan ini ke seluruh kerangka data Anda:
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))
Meskipun Anda bisa mengganti 1:5
dengan jumlah kolom di bingkai data Anda, atau dengan 1:ncol(df)
.
1:5
dengan 1:ncol(df)
di akhir. Saya tidak ingin membuat persamaan terlalu rumit atau sulit dibaca.
1:5
ke nomor kolom yang ingin diubah, seperti 12:15
, tetapi jika Anda ingin mengkonfirmasi bahwa hal itu hanya akan mempengaruhi kolom numerik kemudian hanya membungkus baris kedua fungsi dalam sebuah pernyataan jika, seperti ini: if (is.numeric(col)) { col[col == -1 & is.numeric(col)] <- NA }
.