Dalam bingkai data R yang dikodekan di bawah ini, saya ingin mengganti semua waktu yang B
muncul dengan b
.
junk <- data.frame(x <- rep(LETTERS[1:4], 3), y <- letters[1:12])
colnames(junk) <- c("nm", "val")
ini memberikan:
nm val
1 A a
2 B b
3 C c
4 D d
5 A e
6 B f
7 C g
8 D h
9 A i
10 B j
11 C k
12 D l
Upaya awal saya adalah menggunakan for
dan if
pernyataan seperti ini:
for(i in junk$nm) if(i %in% "B") junk$nm <- "b"
tetapi seperti yang saya yakin Anda bisa lihat, ini menggantikan SEMUA nilai junk$nm
dengan b
. Saya dapat melihat mengapa ini melakukan ini tetapi saya tidak bisa mendapatkannya hanya untuk mengganti kasus sampah $ nm di mana nilai aslinya B
.
CATATAN: Saya berhasil menyelesaikan masalah dengan gsub
tetapi untuk kepentingan belajar RI masih ingin tahu bagaimana cara mendapatkan pendekatan asli saya untuk bekerja (jika memungkinkan)
Jawaban:
Lebih mudah untuk mengubah nm menjadi karakter dan kemudian melakukan perubahan:
EDIT: Dan jika memang Anda perlu mempertahankan nm sebagai faktor, tambahkan ini pada akhirnya:
sumber
cara lain yang berguna untuk mengganti nilai
sumber
Jawaban singkatnya adalah:
Lihatlah vektor Indeks dalam Pendahuluan R (jika Anda belum membacanya).
EDIT. Seperti yang diperhatikan dalam komentar, solusi ini berfungsi untuk vektor karakter jadi gagal pada data Anda.
Untuk faktor cara terbaik adalah dengan mengubah level:
sumber
c("B","C")
. Melakukanjunk$nm[junk$nm == "B"]
adalah cara yang lebih baik.b
ke faktor nm. Versi diliop sebenarnya lebih baik jika Anda ingin bekerja dengan karakter, bukan faktor. (Selalu pikirkan jenis variabel Anda terlebih dahulu!)%in%
dan==
adalahNA
menangani:c(1,2,NA)==1
memberiTRUE, FALSE, NA
tetapic(1,2,NA) %in% 1
memberiTRUE, FALSE, FALSE
. Dan ya saya lupa memeriksa apakah ini berhasil: /Karena data yang Anda tunjukkan adalah faktor, itu sedikit memperumit masalah. Jawaban @ diliop mendekati masalah dengan mengubahnya
nm
menjadi variabel karakter. Untuk kembali ke faktor awal diperlukan langkah lebih lanjut.Alternatifnya adalah memanipulasi level faktor yang ada.
Itu cukup sederhana dan saya sering lupa bahwa ada fungsi pengganti untuk
levels()
.Edit: Seperti dicatat oleh @Seth di komentar, ini dapat dilakukan dalam satu baris, tanpa kehilangan kejelasan:
sumber
levels()
. Bagaimana dengan satu linerjunk <- within(junk, levels(nm)[levels(nm)=="B"] <- "b")
?Cara termudah untuk melakukan ini dalam satu perintah adalah dengan menggunakan
which
perintah dan juga tidak perlu mengubah faktor menjadi karakter dengan melakukan ini:sumber
Anda telah membuat variabel faktor
nm
sehingga Anda perlu menghindarinya atau menambahkan level tambahan ke atribut faktor. Anda juga harus menghindari penggunaan<-
dalam argumen ke data.frame ()Pilihan 1:
Pilihan 2:
sumber
data.frame
?b
sebagai level, cukup ubah levelnyaB
menjadib
.a <- data.frame(x<-1:10)
. Nama kolomnya tidakx
melainkan berantakanx....1.10
. Lebih baik gunakan data.frame (x = 1: 10). Kemudian Anda tahu apa nama kolom Anda.predict()
yang akan mengeluh jika level faktor dalam data baru tidak cocok dengan yang digunakan untuk menyesuaikan model. Lebih bersih dalam jangka panjang untuk mendapatkan data yang diformat sesuai keinginan Anda, dengan benar, daripada mengandalkan jalan pintas. Saya setuju mungkin lebih mudah untuk tidak menjadikannya faktor, tetapi jika sudah menjadi satu, atau perlu menjadi satu untuk beberapa latihan pemodelan ...Jika Anda bekerja dengan variabel karakter (perhatikan yang
stringsAsFactors
salah di sini) Anda dapat menggunakan replace:sumber
Panggil fungsi ini menggunakan baris di bawah ini.
sumber