Saya memiliki bingkai data. Sebut saja dia bob
:
> head(bob)
phenotype exclusion
GSM399350 3- 4- 8- 25- 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399351 3- 4- 8- 25- 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399352 3- 4- 8- 25- 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399353 3- 4- 8- 25+ 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399354 3- 4- 8- 25+ 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399355 3- 4- 8- 25+ 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
Saya ingin menyatukan baris bingkai data ini (ini akan menjadi pertanyaan lain). Tapi lihatlah:
> class(bob$phenotype)
[1] "factor"
Bob
Kolom adalah faktor. Jadi, misalnya:
> as.character(head(bob))
[1] "c(3, 3, 3, 6, 6, 6)" "c(3, 3, 3, 3, 3, 3)"
[3] "c(29, 29, 29, 30, 30, 30)"
Saya tidak mulai memahami hal ini, tetapi saya kira ini adalah indeks-indeks ke dalam tingkat faktor-faktor kolom (pengadilan raja caractacus) bob
? Bukan yang saya butuhkan.
Anehnya saya bisa melalui kolom bob
dengan tangan, dan lakukan
bob$phenotype <- as.character(bob$phenotype)
yang bekerja dengan baik. Dan, setelah mengetik, saya bisa mendapatkan data.frame yang kolomnya karakter daripada faktor. Jadi pertanyaan saya adalah: bagaimana saya bisa melakukan ini secara otomatis? Bagaimana cara mengubah data.frame dengan kolom faktor menjadi data.frame dengan kolom karakter tanpa harus secara manual melalui setiap kolom?
Pertanyaan bonus: mengapa pendekatan manual berfungsi?
bob
.Jawaban:
Mengikuti Matt dan Dirk. Jika Anda ingin membuat ulang bingkai data yang ada tanpa mengubah opsi global, Anda dapat membuatnya kembali dengan pernyataan yang berlaku:
Ini akan mengonversi semua variabel ke "karakter" kelas, jika Anda hanya ingin mengonversi faktor, lihat solusi Marek di bawah ini .
Seperti @hadley tunjukkan, berikut ini lebih ringkas.
Dalam kedua kasus,
lapply
menampilkan daftar; Namun, karena properti magis R, penggunaan[]
dalam kasus kedua menjaga kelas data.framebob
objek, sehingga menghilangkan kebutuhan untuk mengkonversi kembali ke data.frame menggunakanas.data.frame
argumenstringsAsFactors = FALSE
.sumber
type.convert
setelah casting segalanya untukcharacter
, kemudian menyusunfactors
kembali kembali kecharacter
lagi.bob[] <-
dalam contoh ataubob <-
?; yang pertama menyimpan data.frame; yang kedua mengubah data.frame ke daftar, menjatuhkan rownames. Saya akan memperbarui jawabannyairis[] <- lapply(iris, function(x) if (is.factor(x)) as.character(x) else {x})
Untuk mengganti hanya faktor:
Dalam paket dplyr di versi 0.5.0, fungsi baru
mutate_if
diperkenalkan :Paket purrr dari RStudio memberi alternatif lain:
sumber
purrr
Baris mengembalikan daftar, bukandata.frame
!i
vektorcolnames()
.Opsi global
mungkin sesuatu yang ingin Anda atur
FALSE
di file startup Anda (mis. ~ /. Profil). Silakan lihathelp(options)
.sumber
Jika Anda memahami bagaimana faktor disimpan, Anda dapat menghindari menggunakan fungsi berbasis-berlaku untuk mencapai hal ini. Yang sama sekali tidak menyiratkan bahwa solusi yang berlaku tidak berfungsi dengan baik.
Faktor terstruktur sebagai indeks numerik yang diikat ke daftar 'level'. Ini dapat dilihat jika Anda mengonversi faktor menjadi numerik. Begitu:
Angka-angka yang dikembalikan pada baris terakhir sesuai dengan tingkat faktor.
Perhatikan bahwa
levels()
mengembalikan array karakter. Anda dapat menggunakan fakta ini untuk dengan mudah dan kompak mengonversi faktor menjadi string atau angka seperti ini:Ini juga berfungsi untuk nilai numerik, asalkan Anda memasukkan ekspresi Anda
as.numeric()
.sumber
as.character(f)
, lebih baik dalam keterbacaan dan efisiensilevels(f)[as.numeric(f)]
. Jika Anda ingin menjadi pintar, Anda bisa menggunakannyalevels(f)[f]
. Perhatikan bahwa ketika mengonversi faktor dengan nilai numerik, Anda memang mendapatkan manfaat darias.numeric(levels(f))[f]
lebih, misalnyaas.numeric(as.character(f))
, tetapi ini karena Anda hanya perlu mengonversi level menjadi numerik lalu subset.as.character(f)
tidak apa-apa.Jika Anda ingin bingkai data baru di
bobc
mana setiap vektor faktorbobf
dikonversi menjadi vektor karakter, coba ini:Jika Anda ingin mengubahnya kembali, Anda dapat membuat vektor logis dari kolom mana yang merupakan faktor, dan menggunakannya untuk menerapkan faktor secara selektif.
sumber
Saya biasanya membuat fungsi ini terpisah dari semua proyek saya. Cepat dan mudah.
sumber
Cara lain adalah mengonversinya menggunakan apply
Dan yang lebih baik (yang sebelumnya adalah kelas 'matriks')
sumber
as.data.frame(lapply(...
Pembaruan: Berikut adalah contoh dari sesuatu yang tidak berfungsi. Saya pikir itu akan, tetapi saya berpikir bahwa opsi stringsAsFactors hanya bekerja pada string karakter - ia meninggalkan faktor sendirian.
Coba ini:
Secara umum, setiap kali Anda mengalami masalah dengan faktor-faktor yang seharusnya menjadi karakter, ada
stringsAsFactors
pengaturan di suatu tempat untuk membantu Anda (termasuk pengaturan global).sumber
bob
untuk memulai (tetapi tidak setelah fakta).Atau Anda dapat mencoba
transform
:Pastikan untuk memasukkan setiap faktor yang ingin dikonversi menjadi karakter.
Atau Anda dapat melakukan sesuatu seperti ini dan membunuh semua hama dengan satu pukulan:
Ini bukan ide yang baik untuk mendorong data dalam kode seperti ini, aku bisa melakukan
sapply
bagian secara terpisah (sebenarnya, itu jauh lebih mudah untuk melakukannya seperti itu), tetapi Anda mendapatkan intinya ... Saya belum memeriksa kode, karena Saya tidak di rumah, jadi saya harap itu berhasil! =)Pendekatan ini, bagaimanapun, memiliki kerugian ... Anda harus mengatur ulang kolom setelahnya, sementara dengan
transform
Anda dapat melakukan apa pun yang Anda suka, tetapi dengan biaya "wrest-style-code-writting" ...Jadi disana ... =)
sumber
Di awal bingkai data Anda termasuk
stringsAsFactors = FALSE
untuk mengabaikan semua kesalahpahaman.sumber
Jika Anda akan menggunakan
data.table
paket untuk operasi pada data.frame maka masalahnya tidak ada.Jika Anda sudah memiliki kolom faktor dalam dataset Anda dan Anda ingin mengonversinya menjadi karakter, Anda dapat melakukan hal berikut.
sumber
In [<-.data.table(*tmp*, sapply(bob, is.factor), : Coerced 'character' RHS to 'double' to match the column's type. Either change the target column to 'character' first (by creating a new 'character' vector length 1234 (nrows of entire table) and assign that; i.e. 'replace' column), or coerce RHS to 'double' (e.g. 1L, NA_[real|integer]_, as.*, etc) to make your intent clear and for speed. Or, set the column type correctly up front when you create the table and stick to it, please.
Lebih mudah untuk memperbaiki DF dan membuat ulang DT.Ini bekerja untuk saya - saya akhirnya menemukan satu liner
sumber
Fungsi ini berfungsi
sumber
Mungkin opsi yang lebih baru?
sumber
Anda harus menggunakan
convert
dihablar
yang memberikan sintaks dibaca kompatibel dengantidyverse
pipa:yang memberi Anda:
sumber
Dengan penggunaan
dplyr
paket-dimuatjika Anda hanya ingin mengubah
phenotype
kolom-khusus.sumber
Ini berfungsi mentransformasikan semua ke karakter dan kemudian angka ke angka:
Diadaptasi dari: Dapatkan tipe kolom lembar excel secara otomatis
sumber