Untuk berbagi lebih banyak tip dan trik untuk R , apa fitur atau trik Anda yang paling berguna? Vektorisasi pintar? Masukan / keluaran data? Visualisasi dan grafik? Analisis statistik? Fungsi khusus? Lingkungan interaktif itu sendiri?
Satu item per posting, dan kami akan melihat apakah kami mendapatkan pemenang melalui voting.
[Sunting 25-Agustus 2008]: Jadi setelah satu minggu, tampaknya yang sederhana str()memenangkan jajak pendapat. Karena saya sendiri yang ingin merekomendasikannya, ini adalah jawaban yang mudah untuk diterima.
@ars: ini adalah pertanyaan yang tidak memiliki jawaban pasti . Ergo membuatnya menjadi CW.
dmckee --- ex-moderator anak kucing
2
@JD Long komen kocak. sayangnya itu tersembunyi di balik flip. Maksud saya, menjawab pertanyaan R yang sulit tidak benar-benar bermanfaat. Jadi tidak apa-apa bagi saya jika orang yang memberikan pertanyaan bagus yang menempatkan R di peta akhirnya mendapatkan pujian. Selain itu, hal ini tentunya lebih berguna bagi pengguna R daripada pertanyaan trik C favorit Anda bagi pemrogram C ...
Akan sangat berguna untuk mengeposkan potongan data yang dapat direproduksi dengan mudah saat Anda meminta bantuan, atau untuk mengedit atau menyusun ulang level suatu faktor.
head () dan tail () untuk mendapatkan bagian pertama dan terakhir dari kerangka data, vektor, matriks, fungsi, dll. Khususnya dengan bingkai data besar, ini adalah cara cepat untuk memeriksa apakah telah dimuat dengan baik.
Satu fitur bagus: Membaca data menggunakan koneksi yang dapat berupa file lokal, file jarak jauh diakses melalui http, pipa dari program lain atau lebih.
Sebagai contoh sederhana, pertimbangkan akses ini untuk N = 10 bilangan bulat acak antara min = 100 dan max = 200 dari random.org (yang menyediakan bilangan acak sebenarnya berdasarkan kebisingan atmosfer daripada generator bilangan acak semu):
R> site <- "http://random.org/integers/"# base URL
R> query <- "num=10&min=100&max=200&col=2&base=10&format=plain&rnd=new"
R> txt <- paste(site, query, sep="?") # concat url and query string
R> nums <- read.table(file=txt) # and read the data
R> nums # and show it
V1 V2
11651432107118310313241911005138185
R>
Sebagai tambahan, paket acak menyediakan beberapa fungsi kemudahan untuk mengakses random.org .
BTW Saya akan menyarankan bahwa Anda harus membuat selfanswers CW jika (1) Anda posting mereka segera dan (2) Anda tidak membuat pertanyaan CW. Jika tidak, sepertinya Anda mencoba mempermainkan sistem rep. YMMV dan semua itu.
dmckee --- kucing mantan moderator
1
Ini bukan mempermainkan sistem, hanya memulai sesuatu. Dia masih bebas menerima jawaban lain.
ars
2
@ars: Dia bebas menerima yang ini. Saya juga tidak akan berusaha memaksanya untuk menulis wiki jika dia tidak mau menuruti nasihat saya. Tetapi saya tidak akan memposting jawaban mandiri yang telah disiapkan tanpa menandainya sebagai wiki, dan saya juga tidak akan memilih yang tanpa itu. Ambillah itu untuk apa nilainya.
dmckee --- ex-moderator anak kucing
4
@ Dirk: sepenuhnya dapat diterima, bahkan didorong oleh Jeff dan Joel, untuk menjawab pertanyaan Anda sendiri. TIDAK ada persyaratan, bahkan yang informal sekalipun, untuk membuat jawaban Anda CW. Anda jelas tidak mempermainkan sistem. Sekali lagi, abaikan saja polisi wiki komunitas.
Juliet
8
Saya harus setuju bahwa bagian dari tujuan situs adalah memberikan jawaban terbaik untuk masalah umum dan sumber daya umum. Mengajukan pertanyaan dan memberikan jawaban yang baik dapat membantu memperkuat suatu topik. Ini sangat berguna dengan tag baru / kecil seperti R.
kpierce8
35
Saya merasa saya sedang menggunakan with()dan within()lebih banyak lagi. Tidak ada lagi $mengotori kode saya dan seseorang tidak perlu mulai melampirkan objek ke jalur pencarian. Lebih serius lagi, saya menemukan with()dll membuat maksud dari skrip analisis data saya jauh lebih jelas.
> df <- data.frame(A = runif(10), B = rnorm(10))
> A <- 1:10## something else hanging around...
> with(df, A + B) ## I know this will use A in df!
[1] 0.04334784 -0.404446861.993688160.13871605 -1.17734837
[6] 0.424738122.330142261.616907991.419018600.8699079
with()menyiapkan lingkungan di mana ekspresi R dievaluasi. within()melakukan hal yang sama tetapi memungkinkan Anda untuk memodifikasi objek data yang digunakan untuk membuat lingkungan.
> df <- within(df, C <- rpois(10, lambda = 2))
> head(df)
A B C
10.62635571 -0.5830079120.04810539 -0.4525522130.397069791.5966184340.95802501 -0.8193090250.76772541 -1.9450738260.213350060.21138814
Sesuatu yang tidak saya sadari ketika saya pertama kali menggunakan within()adalah bahwa Anda harus melakukan tugas sebagai bagian dari ekspresi yang dievaluasi dan menetapkan objek yang dikembalikan (seperti di atas) untuk mendapatkan efek yang diinginkan.
Menurut saya, Google spreadsheet merupakan cara yang luar biasa bagi semua kolaborator untuk berada di halaman yang sama. Selain itu, Formulir Google memungkinkan seseorang untuk mengambil data dari responden dan dengan mudah menulisnya ke spreadsheet Google. Karena data sering berubah dan hampir tidak pernah final, jauh lebih baik bagi R untuk membaca spreadsheet Google secara langsung daripada langsung mengunduh file csv dan membacanya.
# Get data from google spreadsheetlibrary(RGoogleDocs)
ps <-readline(prompt="get the password in ")
auth = getGoogleAuth("[email protected]", ps, service="wise")
sheets.con <- getGoogleDocsConnection(auth)
ts2=getWorksheets("Data Collection Repos",sheets.con)
names(ts2)
init.consent <-sheetAsMatrix(ts2$Sheet1,header=TRUE, as.data.frame=TRUE, trim=TRUE)
Saya tidak dapat mengingat yang mana kecuali satu atau dua dari perintah berikut membutuhkan beberapa detik.
[Sunting] Dirk bertanya mengapa seseorang memberikan nama yang tidak valid? Saya tidak tahu! Tapi dalam prakteknya saya cukup sering menghadapi masalah ini. Misalnya, menggunakan paket pembentukan kembali hadley:
> library(reshape)
> df$z <- c(1,1,2,2,2)
> recast(df,z~.,id.var="z")
Aggregation requires fun.aggregate: length used as default
z (all)
114226
> recast(df,z~.,id.var="z")$(all)
Error: unexpected '('in"recast(df,z~.,id.var="z")$("
> recast(df,z~.,id.var="z")$`(all)`
Aggregation requires fun.aggregate: length used as default
[1] 46
Oke, tapi mengapa Anda perlu mengganti nama yang valid secara sintaksis (seperti x atau y) dengan yang tidak valid (seperti 1 atau 2) yang membutuhkan backticks?
Dirk Eddelbuettel
3
Ini juga berguna read.tablejika check.namessalah - yaitu saat Anda ingin bekerja dengan nama kolom asli.
hadley
25
Tidak tahu seberapa terkenal ini / tidak, tetapi sesuatu yang pasti saya manfaatkan adalah kemampuan referensi lewat lingkungan.
Hal favorit baru saya adalah perpustakaan foreach. Ini memungkinkan Anda melakukan semua hal terapan yang bagus, tetapi dengan sintaks yang agak lebih mudah:
Bagian terbaiknya adalah jika Anda melakukan sesuatu yang sebenarnya membutuhkan banyak waktu, Anda dapat beralih dari %do%ke %dopar%(dengan pustaka backend yang sesuai) untuk memparalelkan secara instan, bahkan di seluruh kluster. Sangat apik.
Saya melakukan banyak manipulasi data dasar, jadi berikut adalah dua fungsi built-in ( transform , subset ) dan satu library ( sqldf ) yang saya gunakan setiap hari.
membuat contoh data penjualan
sales <- expand.grid(country = c('USA', 'UK', 'FR'),
product = c(1, 2, 3))
sales$revenue <- rnorm(dim(sales)[1], mean=100, sd=10)
> sales
country product revenue
1 USA 1108.459652 UK 197.079813 FR 199.662254 USA 2100.347545 UK 287.122626 FR 2112.860847 USA 395.878808 UK 396.435819 FR 394.59259
gunakan transform () untuk menambahkan kolom
## transform currency to euros
usd2eur <- 1.434
transform(sales, euro = revenue * usd2eur)
>
country product revenue euro
1 USA 1108.45965155.53112 UK 197.07981139.21253 FR 199.66225142.9157...
gunakan sqldf () untuk mengiris dan menggabungkan dengan SQL
The paket sqldf menyediakan sebuah antarmuka SQL untuk data frame R
## recast the previous subset() expression in SQL
sqldf('SELECT product, revenue FROM sales \
WHERE country = "USA" \
AND product IN (1,2)')
>
product revenue
11108.459722100.3475
Lakukan agregasi atau GROUP BY
sqldf('select country, sum(revenue) revenue \
FROM sales \
GROUP BY country')
>
country revenue
1 FR 307.11572 UK 280.63823 USA 304.6860
Untuk fungsionalitas seperti pengurangan peta yang lebih canggih pada bingkai data, lihat paket plyr . Dan jika menemukan diri Anda ingin menarik rambut Anda, saya sarankan memeriksa Manipulasi Data dengan R .
Ada jebakan kecil di sini yang biasa menangkap saya sepanjang waktu. Jika df $ column1 berisi nilai NA, subset menggunakan == akan menarik nilai apa pun yang sama dengan x dan NAs apa pun. Untuk menghindarinya, gunakan "% in%" daripada "==".
Matt Parker
Matt kau benar sekali dan itu sesuatu yang aku benci, aku suka metodemu. Saya biasanya memeriksa kolom untuk NAs dan kemudian menghapusnya dengan fungsi cepat yang saya buat yang mengambil kolom dataframe dan mengembalikan baris dataframe minus dengan NAs hanya di kolom itu.
Dan
pada dasarnya, saya membagi kerangka data ke kolom yang saya perlukan untuk memiliki nilai kemudian menggunakan na.omit untuk mendapatkan baris yang benar dan kemudian subset dataset asli hanya dengan baris tersebut. Hanya menggunakan na.omit akan menghapus baris apa pun dengan NA apa pun, saya bisa saja salah.
Dan
16
Terkadang Anda perlu rbindbeberapa bingkai data. do.call()akan membiarkan Anda melakukan itu (seseorang harus menjelaskan hal ini kepada saya ketika mengikat saya mengajukan pertanyaan ini, karena tampaknya ini bukan penggunaan yang jelas).
Keputusan yang bagus: Saya menemukan bahwa ini seringkali lebih sederhana daripada menggunakan unsplit.
Richie Cotton
16
Dalam pemrograman R (bukan sesi interaktif), saya menggunakan if (bad.condition) stop("message")sebuah banyak . Setiap fungsi dimulai dengan beberapa di antaranya, dan saat saya mengerjakan komputasi, saya juga memasukkannya ke dalamnya. Sepertinya saya terbiasa menggunakan assert()C. Manfaatnya dua kali lipat. Pertama, jauh lebih cepat untuk mendapatkan kode yang berfungsi dengan pemeriksaan ini. Kedua, dan mungkin yang lebih penting, jauh lebih mudah untuk bekerja dengan kode yang ada saat Anda melihat pemeriksaan ini di setiap layar di editor Anda. Anda tidak perlu bertanya-tanya apakah x>0, atau percaya pada komentar yang menyatakan bahwa itu ... Anda akan tahu , dari sekilas, bahwa itu benar.
PS. posting pertama saya disini. Bersikaplah lembut!
Bukan kebiasaan buruk, dan R menawarkan cara lain: stopfifnot(!bad.condition)yang lebih ringkas.
Dirk Eddelbuettel
13
The traceback()Fungsi adalah suatu keharusan ketika Anda memiliki suatu tempat kesalahan dan tidak mengerti mudah. Ini akan mencetak jejak tumpukan, sangat membantu karena R tidak terlalu bertele-tele secara default.
Kemudian pengaturan options(error=recover)akan memungkinkan Anda untuk "masuk" ke dalam fungsi yang meningkatkan kesalahan dan mencoba dan memahami apa yang sebenarnya terjadi, seolah-olah Anda memiliki kendali penuh atas hal itu dan dapat memasukkannya browser()ke dalamnya.
Ketiga fungsi ini benar-benar dapat membantu men-debug kode Anda.
options(error=recover)adalah metode debugging favorit saya.
Joshua Ulrich
12
Saya benar-benar terkejut tidak ada yang memposting tentang apply, tapply, lapply, dan sapply. Aturan umum yang saya gunakan saat melakukan hal-hal di R adalah jika saya memiliki loop for yang melakukan pemrosesan atau simulasi data, saya mencoba memfaktorkannya dan menggantinya dengan * apply. Beberapa orang menghindar dari fungsi * apply karena mereka pikir hanya fungsi parameter tunggal yang dapat diteruskan. Tidak ada yang bisa lebih jauh dari kebenaran! Seperti meneruskan fungsi dengan parameter sebagai objek kelas pertama dalam Javascript, Anda melakukan ini di R dengan fungsi anonim. Sebagai contoh:
> sapply(rnorm(100, 0, 1), round)
[1] 11011 -1 -2022 -2 -101 -101 -10 -100000
[26] 20 -1 -2001 -1151 -1011120 -11 -110 -11
[51] 211 -2 -10 -12 -11 -11 -10 -1 -2110 -1 -11120
[76] 000 -2 -111 -21 -1111000 -1 -30 -100011
> sapply(rnorm(100, 0, 1), round(x, 2)) # How can we pass a parameter?
Error in match.fun(FUN) : object 'x' not found
# Wrap your function call in an anonymous function to use parameters
> sapply(rnorm(100, 0, 1), function(x) {round(x, 2)})
[1] -0.05 -1.74 -0.09 -1.230.69 -1.430.760.550.96 -0.47 -0.81 -0.47
[13] 0.270.320.47 -1.28 -1.44 -1.930.51 -0.82 -0.06 -1.411.23 -0.26
[25] 0.22 -0.04 -2.170.60 -0.10 -0.920.132.621.03 -1.33 -1.73 -0.08
[37] 0.45 -0.930.400.051.09 -1.23 -0.350.620.01 -1.081.70 -1.27
[49] 0.550.60 -1.461.08 -1.88 -0.150.210.060.53 -1.16 -2.13 -0.03
[61] 0.33 -1.070.980.62 -0.01 -0.53 -1.17 -0.28 -0.950.71 -0.58 -0.03
[73] -1.47 -0.75 -0.540.42 -1.630.05 -1.900.40 -0.010.14 -1.581.37
[85] -1.00 -0.901.69 -0.11 -2.19 -0.741.34 -0.75 -0.51 -0.99 -0.36 -1.63
[97] -0.980.611.010.55# Note that anonymous functions aren't being called, but being passed.
> function() {print('hello #rstats')}()
function() {print('hello #rstats')}()
> a = function() {print('hello #rstats')}
> a
function() {print('hello #rstats')}
> a()
[1] "hello #rstats"
(Bagi mereka yang mengikuti #rstats, saya juga memposting ini di sana).
Ingat, gunakan apply, sapply, lapply, tapply, dan do.call! Ambil keuntungan dari vektorisasi R. Anda tidak boleh berjalan ke sekumpulan kode R dan melihat:
N = 10000
l = numeric()
for (i in seq(1:N)) {
sim <- rnorm(1, 0, 1)
l <- rbind(l, sim)
}
Ini tidak hanya tidak vektor, tetapi struktur array di R tidak tumbuh seperti di Python (menggandakan ukuran saat ruang habis, IIRC). Jadi setiap langkah rbind pertama-tama harus tumbuh cukup untuk menerima hasil dari rbind (), lalu salin semua konten l sebelumnya. Untuk bersenang-senang, coba yang di atas di R. Perhatikan berapa lama waktu yang dibutuhkan (Anda bahkan tidak perlu Rprof atau fungsi pengaturan waktu). Kalau begitu coba
N=10000
l <- rnorm(N, 0, 1)
Berikut ini juga lebih baik dari versi pertama:
N = 10000
l = numeric(N)
for (i in seq(1:N)) {
sim <- rnorm(1, 0, 1)
l[i] <- sim
}
apply, sapply, lapply dan tapply berguna. Jika Anda ingin meneruskan parameter ke fungsi bernama seperti round, Anda bisa meneruskannya dengan apply daripada menulis fungsi anonim. Coba "sapply (rnorm (10, 0, 1), round, digits = 2)" yang menghasilkan "[1] -0.29 0.29 1.31 -0.06 -1.90 -0.84 0.21 0.02 0.23 -1.10".
Daniel
11
Atas saran Dirk, saya memposting satu contoh. Saya berharap mereka tidak terlalu "manis" [pintar, tapi saya tidak peduli] atau remeh untuk penonton ini.
Model linier adalah roti dan mentega dari R. Ketika jumlah variabel independen tinggi, seseorang memiliki dua pilihan. Yang pertama adalah menggunakan lm.fit (), yang menerima matriks desain x dan respons y sebagai argumen, mirip dengan Matlab. Kelemahan dari pendekatan ini adalah bahwa nilai yang dikembalikan adalah daftar objek (koefisien yang dipasang, residual, dll), bukan objek kelas "lm", yang dapat diringkas dengan baik, digunakan untuk prediksi, pemilihan bertahap, dll. Pendekatan membuat rumus:
> A
X1 X2 X3 X4 y
10.968523630.338271070.2613322570.628170211.642532620.080127550.691598280.0879941580.937804810.980130430.101675450.381193040.8652098320.165016620.483087340.066994580.417564150.2580716160.340277750.7508766...
> (f=paste("y ~",paste(names(A)[1:4],collapse=" + ")))
[1] "y ~ X1 + X2 + X3 + X4"
> lm(formula(f),data=A)
Call:
lm(formula = formula(f), data = A)
Coefficients:
(Intercept) X1 X2 X3 X4
0.782360.95406 -0.06738 -0.43686 -0.06644
Bagaimana jika Anda memilih satu per posting dan mengilustrasikan dengan contoh? Kami kemudian dapat terus berjalan selama berhari-hari dan mengirim contoh baru dengan perintah baru ... [BTW: Seingat saya, Anda memerlukan as.formula (paste (...)) untuk penggunaan rumus. ]
Dirk Eddelbuettel
Anda tidak memerlukan pembuatan rumus secara eksplisit untuk mencakup semua kolom karena formulir "y ~. - 1" mencakupnya. The "." berarti 'semua kolom kecuali variabel dependen, dan' - 1 'tidak termasuk konstanta seperti pada contoh Anda.
Dirk Eddelbuettel
Itu benar untuk contoh khusus ini, tetapi untuk X dengan ncols >> nrows, saya sering menghapus beberapa variabel independen, terutama pada tahap akhir analisis. Dalam hal ini, membuat rumus dari nama bingkai data masih berguna.
gappy
10
Anda dapat menetapkan nilai yang dikembalikan dari blok if-else.
Dari pada, mis
condition <- runif(1) > 0.5if(condition) x <- 1else x <- 2
Anda juga dapat melakukan ini seperti x <- ifelse (condition, 1, 2), dalam hal ini setiap komponen divektorisasi.
Shane
Shane, Anda bisa, tetapi kecuali Anda benar-benar memahami apa yang dilakukan ifelse (), Anda mungkin tidak boleh melakukannya! Sangat mudah untuk salah paham ...
Harlan
Apa yang ajaib tentang itu? Itulah cara if-then-elseekspresi bekerja dalam bahasa fungsional apa pun (jangan disamakan dengan if-then-elsepernyataan ). Sangat mirip dengan ?:operator terner bahasa mirip C.
Frank
10
Sebagai pemula total untuk R dan pemula di statistik, saya suka unclass()
mencetak semua elemen bingkai data sebagai daftar biasa.
Ini sangat berguna untuk melihat kumpulan data lengkap sekaligus untuk melihat dengan cepat masalah potensial apa pun.
CrossTable()dari gmodelspaket menyediakan akses mudah ke tab silang gaya SAS dan SPSS, bersama dengan pengujian biasa (Chisq, McNemar, dll.). Pada dasarnya, ini xtabs()dengan keluaran mewah dan beberapa tes tambahan - tetapi itu membuat keluaran berbagi dengan kafir lebih mudah.
Bagus!! Saya cukup sering menggunakan gmodels, tapi melewatkan yang itu
Abhijit
Jawaban yang bagus, apapun yang dapat menjauhkan saya dari penjelasan tabel yang berlebihan dengan para kafir adalah penggunaan waktu yang baik.
Stedy
7
Pasti system(). Untuk dapat memiliki akses ke semua alat unix (setidaknya di Linux / MacOSX) dari dalam lingkungan R dengan cepat menjadi sangat berharga dalam alur kerja harian saya.
Itu terkait dengan komentar saya sebelumnya tentang koneksi: Anda juga dapat menggunakan pipa () untuk meneruskan data dari, atau ke, perintah Unix. Lihat help(connections)detail dan contoh.
Dirk Eddelbuettel
6
Berikut adalah solusi yang mengganggu untuk mengubah faktor menjadi numerik. (Serupa untuk tipe data lain juga)
Mungkin yang Anda maksud adalah vektor "menjadi karakter". Dalam hal ini "as.character (old.var)" lebih sederhana.
Dirk Eddelbuettel
1
Saya selalu menganggap nasihat ini (yang dapat dibaca di? Faktor) salah arah. Anda harus memastikan old.var adalah faktor, dan ini akan bervariasi sesuai dengan opsi yang Anda tetapkan untuk sesi R. Menggunakan as.numeric (as.character (old.var)) lebih aman dan lebih bersih.
Eduardo Leoni
Benar-benar tidak layak untuk downvote, tapi terserah. Ini berhasil untuk saya.
Ryan R. Rosario
Ryan - Bisakah Anda memperbaiki kode Anda? Jika old.var <- factor (1: 2); kode Anda akan memberikan [1] "1" "2" (bukan numerik.) mungkin yang Anda maksud sebagai.numerik (level (old.var) [old.var])?
Eduardo Leoni
3
Atau sedikit lebih efisien:as.numeric(levels(old.var))[old.var]
hadley
6
Meskipun pertanyaan ini telah muncul untuk beberapa waktu, saya baru-baru ini menemukan trik hebat di blog SAS dan R untuk menggunakan perintah cut. Perintah tersebut digunakan untuk membagi data menjadi beberapa kategori dan saya akan menggunakan dataset iris sebagai contoh dan membaginya menjadi 10 kategori:
Trik lain. Beberapa paket, seperti glmnet, hanya menerima matriks desain dan variabel respons sebagai masukan. Jika seseorang ingin menyesuaikan model dengan semua interaksi antara fitur, dia tidak dapat menggunakan rumus "y ~. ^ 2". Menggunakan expand.grid()memungkinkan kita untuk memanfaatkan pengindeksan array yang kuat dan operasi vektor R.
Jika fungsi pemodelan tidak menerima rumus (yang sangat jarang!) Bukankah lebih baik untuk membuat matriks desain dengan model.matrix?
hadley
Bagus. Saya tidak tahu keberadaan fungsi ini. Fungsi di atas setara dengan model.matrix (~. ^ 2 -1, X) Tetapi mengenai matriks yang lewat, selain dari glmnet, saya sering melewatkan pointer array ke fungsi C kustom. Memang, saya tidak akan tahu cara meneruskan rumus ke suatu fungsi. Apakah Anda punya contoh mainan?
gappy
5
Salah satu trik favorit saya, jika bukan merupakan trik ortodoks, adalah penggunaan eval()dan parse(). Contoh ini mungkin menggambarkan bagaimana itu dapat membantu
Jenis situasi ini terjadi lebih sering daripada tidak, dan penggunaan eval()dan parse()dapat membantu mengatasinya. Tentu saja, saya menyambut baik umpan balik tentang cara alternatif pengkodean ini.
Ini bisa dilakukan juga dengan elemen vektor bernama.
Dirk Eddelbuettel
3
library (fortunes); fortune (106) Jika jawabannya adalah parse () Anda biasanya harus memikirkan kembali pertanyaannya. - Thomas Lumley R-help (Februari 2005)
Eduardo Leoni
Berikut adalah contoh di mana eval () dan parse () bisa berguna. Ini melibatkan paket Biokonduktor, misalnya hgu133a.db dan di mana Anda mencoba mendapatkan berbagai informasi tentang id probe. Misalnya: parameter library (hgu133a.db) <- 'SYMBOL' mget ('202431_s_at', env = eval (parse (text = paste ('hgu133a', parameter, sep = '')))) parameter <- 'ENTREZID 'mget (' 202431_s_at ', env = eval (parse (text = paste (' hgu133a ', parameter, sep =' '))))
andrewj
Seperti yang dikatakan Dirk, ini lebih baik dilakukan dengan elemen vektor bernama, atau `get (paste (state, parameter, sep = '.'))`
hadley
@Hadley, tidak tahu bahwa Anda bisa menggunakan get () seperti itu. Terima kasih.
untuk (f dalam file) {if (! (f == 'mysource.r')) {print (paste ('Sourcing', f)) source (paste (d, f, sep = ''))}}
Saya menggunakan kode di atas untuk sumber semua file dalam direktori saat memulai dengan berbagai program utilitas yang saya gunakan dalam sesi interaktif saya dengan R. Saya yakin ada cara yang lebih baik tetapi saya merasa berguna untuk pekerjaan saya. Garis yang melakukan ini adalah sebagai berikut.
Terima kasih. Saya telah melihat satu atau dua utas tentang roxygen dan tampaknya saya mungkin berada pada level di mana saya harus mencoba menulis paket penggunaan mandiri sederhana.
mcheema
3
Untuk melakukan operasi pada sejumlah variabel dalam bingkai data. Ini dicuri dari subset.data.frame.
get.vars<-function(vars,data){
nl <- as.list(1L:ncol(data))
names(nl) <- names(data)
vars <- eval(substitute(vars), nl, parent.frame())
data[,vars]
#do stuff here
}
get.vars(c(cyl:hwy,class),mpg)
Ini tampak keren pada awalnya, tetapi kode semacam ini akan menyebabkan Anda mengalami masalah yang tidak ada habisnya dalam jangka panjang. Lebih baik bersikap eksplisit.
hadley
hum, saya telah menggunakan trik ini cukup banyak akhir-akhir ini. Bisakah Anda lebih spesifik tentang masalahnya yang tidak terbatas?
Ian Fellows
Mungkin hadley menyarankan untuk menggunakan paket plyr?
Christopher DuBois
3
Tidak, ini bukan saran terselubung untuk menggunakan plyr. Pada dasarnya masalah dengan kode Anda adalah bahwa kode itu malas secara semantik - alih-alih membuat pengguna secara eksplisit mengeja apa yang mereka inginkan, Anda melakukan "sihir" untuk menebak. Masalahnya adalah hal ini membuat fungsi menjadi sangat sulit untuk diprogram - yaitu sulit untuk menulis fungsi yang memanggil get.varstanpa melewati banyak rintangan.
hadley
3
Saya telah memposting ini sekali sebelumnya tetapi saya sering menggunakannya sehingga saya pikir saya akan mempostingnya lagi. Ini hanya sedikit fungsinya untuk mengembalikan nama dan nomor posisi dari data.frame. Tidak ada yang istimewa untuk memastikannya, tetapi saya hampir tidak pernah berhasil melewati sesi tanpa menggunakannya beberapa kali.
##creates an object from a data.frame listing the column names and location
Jawaban:
str()
memberi tahu Anda struktur objek apa pun.sumber
dir()
- lebih masuk akal.str
juga kependekan daristring
banyak bahasa.class()
? Tampaknya mengungkapkan jenis informasi yang serupa. Mengapa ada dua perintah yang serupa?class()
hanyalah sebagian kecil dari informasi yangstr()
ditampilkanSalah satu fungsi yang sangat berguna yang sering saya gunakan adalah dput (), yang memungkinkan Anda membuang objek dalam bentuk kode R.
# Use the iris data set R> data(iris) # dput of a numeric vector R> dput(iris$Petal.Length) c(1.4, 1.4, 1.3, 1.5, 1.4, 1.7, 1.4, 1.5, 1.4, 1.5, 1.5, 1.6, 1.4, 1.1, 1.2, 1.5, 1.3, 1.4, 1.7, 1.5, 1.7, 1.5, 1, 1.7, 1.9, 1.6, 1.6, 1.5, 1.4, 1.6, 1.6, 1.5, 1.5, 1.4, 1.5, 1.2, 1.3, 1.4, 1.3, 1.5, 1.3, 1.3, 1.3, 1.6, 1.9, 1.4, 1.6, 1.4, 1.5, 1.4, 4.7, 4.5, 4.9, 4, 4.6, 4.5, 4.7, 3.3, 4.6, 3.9, 3.5, 4.2, 4, 4.7, 3.6, 4.4, 4.5, 4.1, 4.5, 3.9, 4.8, 4, 4.9, 4.7, 4.3, 4.4, 4.8, 5, 4.5, 3.5, 3.8, 3.7, 3.9, 5.1, 4.5, 4.5, 4.7, 4.4, 4.1, 4, 4.4, 4.6, 4, 3.3, 4.2, 4.2, 4.2, 4.3, 3, 4.1, 6, 5.1, 5.9, 5.6, 5.8, 6.6, 4.5, 6.3, 5.8, 6.1, 5.1, 5.3, 5.5, 5, 5.1, 5.3, 5.5, 6.7, 6.9, 5, 5.7, 4.9, 6.7, 4.9, 5.7, 6, 4.8, 4.9, 5.6, 5.8, 6.1, 6.4, 5.6, 5.1, 5.6, 6.1, 5.6, 5.5, 4.8, 5.4, 5.6, 5.1, 5.1, 5.9, 5.7, 5.2, 5, 5.2, 5.4, 5.1) # dput of a factor levels R> dput(levels(iris$Species)) c("setosa", "versicolor", "virginica")
Akan sangat berguna untuk mengeposkan potongan data yang dapat direproduksi dengan mudah saat Anda meminta bantuan, atau untuk mengedit atau menyusun ulang level suatu faktor.
sumber
head () dan tail () untuk mendapatkan bagian pertama dan terakhir dari kerangka data, vektor, matriks, fungsi, dll. Khususnya dengan bingkai data besar, ini adalah cara cepat untuk memeriksa apakah telah dimuat dengan baik.
sumber
Satu fitur bagus: Membaca data menggunakan koneksi yang dapat berupa file lokal, file jarak jauh diakses melalui http, pipa dari program lain atau lebih.
Sebagai contoh sederhana, pertimbangkan akses ini untuk N = 10 bilangan bulat acak antara min = 100 dan max = 200 dari random.org (yang menyediakan bilangan acak sebenarnya berdasarkan kebisingan atmosfer daripada generator bilangan acak semu):
R> site <- "http://random.org/integers/" # base URL R> query <- "num=10&min=100&max=200&col=2&base=10&format=plain&rnd=new" R> txt <- paste(site, query, sep="?") # concat url and query string R> nums <- read.table(file=txt) # and read the data R> nums # and show it V1 V2 1 165 143 2 107 118 3 103 132 4 191 100 5 138 185 R>
Sebagai tambahan, paket acak menyediakan beberapa fungsi kemudahan untuk mengakses random.org .
sumber
Saya merasa saya sedang menggunakan
with()
danwithin()
lebih banyak lagi. Tidak ada lagi$
mengotori kode saya dan seseorang tidak perlu mulai melampirkan objek ke jalur pencarian. Lebih serius lagi, saya menemukanwith()
dll membuat maksud dari skrip analisis data saya jauh lebih jelas.> df <- data.frame(A = runif(10), B = rnorm(10)) > A <- 1:10 ## something else hanging around... > with(df, A + B) ## I know this will use A in df! [1] 0.04334784 -0.40444686 1.99368816 0.13871605 -1.17734837 [6] 0.42473812 2.33014226 1.61690799 1.41901860 0.8699079
with()
menyiapkan lingkungan di mana ekspresi R dievaluasi.within()
melakukan hal yang sama tetapi memungkinkan Anda untuk memodifikasi objek data yang digunakan untuk membuat lingkungan.> df <- within(df, C <- rpois(10, lambda = 2)) > head(df) A B C 1 0.62635571 -0.5830079 1 2 0.04810539 -0.4525522 1 3 0.39706979 1.5966184 3 4 0.95802501 -0.8193090 2 5 0.76772541 -1.9450738 2 6 0.21335006 0.2113881 4
Sesuatu yang tidak saya sadari ketika saya pertama kali menggunakan
within()
adalah bahwa Anda harus melakukan tugas sebagai bagian dari ekspresi yang dievaluasi dan menetapkan objek yang dikembalikan (seperti di atas) untuk mendapatkan efek yang diinginkan.sumber
Trik Masukan Data = paket RGoogleDocs
http://www.omegahat.org/RGoogleDocs/
Menurut saya, Google spreadsheet merupakan cara yang luar biasa bagi semua kolaborator untuk berada di halaman yang sama. Selain itu, Formulir Google memungkinkan seseorang untuk mengambil data dari responden dan dengan mudah menulisnya ke spreadsheet Google. Karena data sering berubah dan hampir tidak pernah final, jauh lebih baik bagi R untuk membaca spreadsheet Google secara langsung daripada langsung mengunduh file csv dan membacanya.
# Get data from google spreadsheet library(RGoogleDocs) ps <-readline(prompt="get the password in ") auth = getGoogleAuth("[email protected]", ps, service="wise") sheets.con <- getGoogleDocsConnection(auth) ts2=getWorksheets("Data Collection Repos",sheets.con) names(ts2) init.consent <-sheetAsMatrix(ts2$Sheet1,header=TRUE, as.data.frame=TRUE, trim=TRUE)
Saya tidak dapat mengingat yang mana kecuali satu atau dua dari perintah berikut membutuhkan beberapa detik.
getGoogleAuth
getGoogleDocsConnection
getWorksheets
sumber
Gunakan backticks untuk mereferensikan nama non standar.
> df <- data.frame(x=rnorm(5),y=runif(5)) > names(df) <- 1:2 > df 1 2 1 -1.2035003 0.6989573 2 -1.2146266 0.8272276 3 0.3563335 0.0947696 4 -0.4372646 0.9765767 5 -0.9952423 0.6477714 > df$1 Error: unexpected numeric constant in "df$1" > df$`1` [1] -1.2035003 -1.2146266 0.3563335 -0.4372646 -0.9952423
Dalam hal ini, df [, "1"] juga akan berfungsi. Tapi kutu belakang bekerja di dalam formula!
> lm(`2`~`1`,data=df) Call: lm(formula = `2` ~ `1`, data = df) Coefficients: (Intercept) `1` 0.4087 -0.3440
[Sunting] Dirk bertanya mengapa seseorang memberikan nama yang tidak valid? Saya tidak tahu! Tapi dalam prakteknya saya cukup sering menghadapi masalah ini. Misalnya, menggunakan paket pembentukan kembali hadley:
> library(reshape) > df$z <- c(1,1,2,2,2) > recast(df,z~.,id.var="z") Aggregation requires fun.aggregate: length used as default z (all) 1 1 4 2 2 6 > recast(df,z~.,id.var="z")$(all) Error: unexpected '(' in "recast(df,z~.,id.var="z")$(" > recast(df,z~.,id.var="z")$`(all)` Aggregation requires fun.aggregate: length used as default [1] 4 6
sumber
read.table
jikacheck.names
salah - yaitu saat Anda ingin bekerja dengan nama kolom asli.Tidak tahu seberapa terkenal ini / tidak, tetapi sesuatu yang pasti saya manfaatkan adalah kemampuan referensi lewat lingkungan.
zz <- new.env() zz$foo <- c(1,2,3,4,5) changer <- function(blah) { blah$foo <- 5 } changer(zz) zz$foo
Untuk contoh ini tidak masuk akal mengapa ini berguna, tetapi jika Anda melewati objek besar di sekitarnya, itu dapat membantu.
sumber
Hal favorit baru saya adalah perpustakaan foreach. Ini memungkinkan Anda melakukan semua hal terapan yang bagus, tetapi dengan sintaks yang agak lebih mudah:
list_powers <- foreach(i = 1:100) %do% { lp <- x[i]^i return (lp) }
Bagian terbaiknya adalah jika Anda melakukan sesuatu yang sebenarnya membutuhkan banyak waktu, Anda dapat beralih dari
%do%
ke%dopar%
(dengan pustaka backend yang sesuai) untuk memparalelkan secara instan, bahkan di seluruh kluster. Sangat apik.sumber
Saya melakukan banyak manipulasi data dasar, jadi berikut adalah dua fungsi built-in ( transform , subset ) dan satu library ( sqldf ) yang saya gunakan setiap hari.
membuat contoh data penjualan
sales <- expand.grid(country = c('USA', 'UK', 'FR'), product = c(1, 2, 3)) sales$revenue <- rnorm(dim(sales)[1], mean=100, sd=10) > sales country product revenue 1 USA 1 108.45965 2 UK 1 97.07981 3 FR 1 99.66225 4 USA 2 100.34754 5 UK 2 87.12262 6 FR 2 112.86084 7 USA 3 95.87880 8 UK 3 96.43581 9 FR 3 94.59259
gunakan transform () untuk menambahkan kolom
## transform currency to euros usd2eur <- 1.434 transform(sales, euro = revenue * usd2eur) > country product revenue euro 1 USA 1 108.45965 155.5311 2 UK 1 97.07981 139.2125 3 FR 1 99.66225 142.9157 ...
gunakan subset () untuk memotong data
subset(sales, country == 'USA' & product %in% c(1, 2), select = c('product', 'revenue')) > product revenue 1 1 108.4597 4 2 100.3475
gunakan sqldf () untuk mengiris dan menggabungkan dengan SQL
The paket sqldf menyediakan sebuah antarmuka SQL untuk data frame R
## recast the previous subset() expression in SQL sqldf('SELECT product, revenue FROM sales \ WHERE country = "USA" \ AND product IN (1,2)') > product revenue 1 1 108.4597 2 2 100.3475
Lakukan agregasi atau GROUP BY
sqldf('select country, sum(revenue) revenue \ FROM sales \ GROUP BY country') > country revenue 1 FR 307.1157 2 UK 280.6382 3 USA 304.6860
Untuk fungsionalitas seperti pengurangan peta yang lebih canggih pada bingkai data, lihat paket plyr . Dan jika menemukan diri Anda ingin menarik rambut Anda, saya sarankan memeriksa Manipulasi Data dengan R .
sumber
Subset dari 'x []' dirata-ratakan, di mana setiap subset terdiri dari observasi dengan tingkat faktor yang sama. Penggunaan: ave (x, ..., FUN = mean)
Saya menggunakannya sepanjang waktu. (misalnya dalam jawaban ini di sini )
sumber
Cara untuk mempercepat kode dan menghilangkan loop.
bukannya untuk loop yang mengulang melalui dataframe mencari nilai. ambil saja subset dari df dengan nilai tersebut, lebih cepat.
jadi alih-alih:
for(i in 1:nrow(df)){ if (df$column[i] == x) { df$column2[i] <- y or any other similiar code } }
lakukan sesuatu seperti ini:
konsep dasar itu sangat sering diterapkan dan merupakan cara terbaik untuk menghilangkan loop
sumber
Terkadang Anda perlu
rbind
beberapa bingkai data.do.call()
akan membiarkan Anda melakukan itu (seseorang harus menjelaskan hal ini kepada saya ketika mengikat saya mengajukan pertanyaan ini, karena tampaknya ini bukan penggunaan yang jelas).foo <- list() foo[[1]] <- data.frame(a=1:5, b=11:15) foo[[2]] <- data.frame(a=101:105, b=111:115) foo[[3]] <- data.frame(a=200:210, b=300:310) do.call(rbind, foo)
sumber
unsplit
.Dalam pemrograman R (bukan sesi interaktif), saya menggunakan
if (bad.condition) stop("message")
sebuah banyak . Setiap fungsi dimulai dengan beberapa di antaranya, dan saat saya mengerjakan komputasi, saya juga memasukkannya ke dalamnya. Sepertinya saya terbiasa menggunakanassert()
C. Manfaatnya dua kali lipat. Pertama, jauh lebih cepat untuk mendapatkan kode yang berfungsi dengan pemeriksaan ini. Kedua, dan mungkin yang lebih penting, jauh lebih mudah untuk bekerja dengan kode yang ada saat Anda melihat pemeriksaan ini di setiap layar di editor Anda. Anda tidak perlu bertanya-tanya apakahx>0
, atau percaya pada komentar yang menyatakan bahwa itu ... Anda akan tahu , dari sekilas, bahwa itu benar.PS. posting pertama saya disini. Bersikaplah lembut!
sumber
stopfifnot(!bad.condition)
yang lebih ringkas.The
traceback()
Fungsi adalah suatu keharusan ketika Anda memiliki suatu tempat kesalahan dan tidak mengerti mudah. Ini akan mencetak jejak tumpukan, sangat membantu karena R tidak terlalu bertele-tele secara default.Kemudian pengaturan
options(error=recover)
akan memungkinkan Anda untuk "masuk" ke dalam fungsi yang meningkatkan kesalahan dan mencoba dan memahami apa yang sebenarnya terjadi, seolah-olah Anda memiliki kendali penuh atas hal itu dan dapat memasukkannyabrowser()
ke dalamnya.Ketiga fungsi ini benar-benar dapat membantu men-debug kode Anda.
sumber
options(error=recover)
adalah metode debugging favorit saya.Saya benar-benar terkejut tidak ada yang memposting tentang apply, tapply, lapply, dan sapply. Aturan umum yang saya gunakan saat melakukan hal-hal di R adalah jika saya memiliki loop for yang melakukan pemrosesan atau simulasi data, saya mencoba memfaktorkannya dan menggantinya dengan * apply. Beberapa orang menghindar dari fungsi * apply karena mereka pikir hanya fungsi parameter tunggal yang dapat diteruskan. Tidak ada yang bisa lebih jauh dari kebenaran! Seperti meneruskan fungsi dengan parameter sebagai objek kelas pertama dalam Javascript, Anda melakukan ini di R dengan fungsi anonim. Sebagai contoh:
> sapply(rnorm(100, 0, 1), round) [1] 1 1 0 1 1 -1 -2 0 2 2 -2 -1 0 1 -1 0 1 -1 0 -1 0 0 0 0 0 [26] 2 0 -1 -2 0 0 1 -1 1 5 1 -1 0 1 1 1 2 0 -1 1 -1 1 0 -1 1 [51] 2 1 1 -2 -1 0 -1 2 -1 1 -1 1 -1 0 -1 -2 1 1 0 -1 -1 1 1 2 0 [76] 0 0 0 -2 -1 1 1 -2 1 -1 1 1 1 0 0 0 -1 -3 0 -1 0 0 0 1 1 > sapply(rnorm(100, 0, 1), round(x, 2)) # How can we pass a parameter? Error in match.fun(FUN) : object 'x' not found # Wrap your function call in an anonymous function to use parameters > sapply(rnorm(100, 0, 1), function(x) {round(x, 2)}) [1] -0.05 -1.74 -0.09 -1.23 0.69 -1.43 0.76 0.55 0.96 -0.47 -0.81 -0.47 [13] 0.27 0.32 0.47 -1.28 -1.44 -1.93 0.51 -0.82 -0.06 -1.41 1.23 -0.26 [25] 0.22 -0.04 -2.17 0.60 -0.10 -0.92 0.13 2.62 1.03 -1.33 -1.73 -0.08 [37] 0.45 -0.93 0.40 0.05 1.09 -1.23 -0.35 0.62 0.01 -1.08 1.70 -1.27 [49] 0.55 0.60 -1.46 1.08 -1.88 -0.15 0.21 0.06 0.53 -1.16 -2.13 -0.03 [61] 0.33 -1.07 0.98 0.62 -0.01 -0.53 -1.17 -0.28 -0.95 0.71 -0.58 -0.03 [73] -1.47 -0.75 -0.54 0.42 -1.63 0.05 -1.90 0.40 -0.01 0.14 -1.58 1.37 [85] -1.00 -0.90 1.69 -0.11 -2.19 -0.74 1.34 -0.75 -0.51 -0.99 -0.36 -1.63 [97] -0.98 0.61 1.01 0.55 # Note that anonymous functions aren't being called, but being passed. > function() {print('hello #rstats')}() function() {print('hello #rstats')}() > a = function() {print('hello #rstats')} > a function() {print('hello #rstats')} > a() [1] "hello #rstats"
(Bagi mereka yang mengikuti #rstats, saya juga memposting ini di sana).
Ingat, gunakan apply, sapply, lapply, tapply, dan do.call! Ambil keuntungan dari vektorisasi R. Anda tidak boleh berjalan ke sekumpulan kode R dan melihat:
N = 10000 l = numeric() for (i in seq(1:N)) { sim <- rnorm(1, 0, 1) l <- rbind(l, sim) }
Ini tidak hanya tidak vektor, tetapi struktur array di R tidak tumbuh seperti di Python (menggandakan ukuran saat ruang habis, IIRC). Jadi setiap langkah rbind pertama-tama harus tumbuh cukup untuk menerima hasil dari rbind (), lalu salin semua konten l sebelumnya. Untuk bersenang-senang, coba yang di atas di R. Perhatikan berapa lama waktu yang dibutuhkan (Anda bahkan tidak perlu Rprof atau fungsi pengaturan waktu). Kalau begitu coba
N=10000 l <- rnorm(N, 0, 1)
Berikut ini juga lebih baik dari versi pertama:
N = 10000 l = numeric(N) for (i in seq(1:N)) { sim <- rnorm(1, 0, 1) l[i] <- sim }
sumber
Atas saran Dirk, saya memposting satu contoh. Saya berharap mereka tidak terlalu "manis" [pintar, tapi saya tidak peduli] atau remeh untuk penonton ini.
Model linier adalah roti dan mentega dari R. Ketika jumlah variabel independen tinggi, seseorang memiliki dua pilihan. Yang pertama adalah menggunakan lm.fit (), yang menerima matriks desain x dan respons y sebagai argumen, mirip dengan Matlab. Kelemahan dari pendekatan ini adalah bahwa nilai yang dikembalikan adalah daftar objek (koefisien yang dipasang, residual, dll), bukan objek kelas "lm", yang dapat diringkas dengan baik, digunakan untuk prediksi, pemilihan bertahap, dll. Pendekatan membuat rumus:
> A X1 X2 X3 X4 y 1 0.96852363 0.33827107 0.261332257 0.62817021 1.6425326 2 0.08012755 0.69159828 0.087994158 0.93780481 0.9801304 3 0.10167545 0.38119304 0.865209832 0.16501662 0.4830873 4 0.06699458 0.41756415 0.258071616 0.34027775 0.7508766 ... > (f=paste("y ~",paste(names(A)[1:4],collapse=" + "))) [1] "y ~ X1 + X2 + X3 + X4" > lm(formula(f),data=A) Call: lm(formula = formula(f), data = A) Coefficients: (Intercept) X1 X2 X3 X4 0.78236 0.95406 -0.06738 -0.43686 -0.06644
sumber
Anda dapat menetapkan nilai yang dikembalikan dari blok if-else.
Dari pada, mis
condition <- runif(1) > 0.5 if(condition) x <- 1 else x <- 2
Anda dapat melakukan
x <- if(condition) 1 else 2
Cara kerjanya adalah sihir yang dalam.
sumber
if-then-else
ekspresi bekerja dalam bahasa fungsional apa pun (jangan disamakan denganif-then-else
pernyataan ). Sangat mirip dengan?:
operator terner bahasa mirip C.Sebagai pemula total untuk R dan pemula di statistik, saya suka
unclass()
mencetak semua elemen bingkai data sebagai daftar biasa.Ini sangat berguna untuk melihat kumpulan data lengkap sekaligus untuk melihat dengan cepat masalah potensial apa pun.
sumber
CrossTable()
darigmodels
paket menyediakan akses mudah ke tab silang gaya SAS dan SPSS, bersama dengan pengujian biasa (Chisq, McNemar, dll.). Pada dasarnya, inixtabs()
dengan keluaran mewah dan beberapa tes tambahan - tetapi itu membuat keluaran berbagi dengan kafir lebih mudah.sumber
Pasti
system()
. Untuk dapat memiliki akses ke semua alat unix (setidaknya di Linux / MacOSX) dari dalam lingkungan R dengan cepat menjadi sangat berharga dalam alur kerja harian saya.sumber
help(connections)
detail dan contoh.Berikut adalah solusi yang mengganggu untuk mengubah faktor menjadi numerik. (Serupa untuk tipe data lain juga)
sumber
as.numeric(levels(old.var))[old.var]
Meskipun pertanyaan ini telah muncul untuk beberapa waktu, saya baru-baru ini menemukan trik hebat di blog SAS dan R untuk menggunakan perintah
cut
. Perintah tersebut digunakan untuk membagi data menjadi beberapa kategori dan saya akan menggunakan dataset iris sebagai contoh dan membaginya menjadi 10 kategori:> irisSL <- iris$Sepal.Length > str(irisSL) num [1:150] 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... > cut(irisSL, 10) [1] (5.02,5.38] (4.66,5.02] (4.66,5.02] (4.3,4.66] (4.66,5.02] (5.38,5.74] (4.3,4.66] (4.66,5.02] (4.3,4.66] (4.66,5.02] [11] (5.38,5.74] (4.66,5.02] (4.66,5.02] (4.3,4.66] (5.74,6.1] (5.38,5.74] (5.38,5.74] (5.02,5.38] (5.38,5.74] (5.02,5.38] [21] (5.38,5.74] (5.02,5.38] (4.3,4.66] (5.02,5.38] (4.66,5.02] (4.66,5.02] (4.66,5.02] (5.02,5.38] (5.02,5.38] (4.66,5.02] [31] (4.66,5.02] (5.38,5.74] (5.02,5.38] (5.38,5.74] (4.66,5.02] (4.66,5.02] (5.38,5.74] (4.66,5.02] (4.3,4.66] (5.02,5.38] [41] (4.66,5.02] (4.3,4.66] (4.3,4.66] (4.66,5.02] (5.02,5.38] (4.66,5.02] (5.02,5.38] (4.3,4.66] (5.02,5.38] (4.66,5.02] [51] (6.82,7.18] (6.1,6.46] (6.82,7.18] (5.38,5.74] (6.46,6.82] (5.38,5.74] (6.1,6.46] (4.66,5.02] (6.46,6.82] (5.02,5.38] [61] (4.66,5.02] (5.74,6.1] (5.74,6.1] (5.74,6.1] (5.38,5.74] (6.46,6.82] (5.38,5.74] (5.74,6.1] (6.1,6.46] (5.38,5.74] [71] (5.74,6.1] (5.74,6.1] (6.1,6.46] (5.74,6.1] (6.1,6.46] (6.46,6.82] (6.46,6.82] (6.46,6.82] (5.74,6.1] (5.38,5.74] [81] (5.38,5.74] (5.38,5.74] (5.74,6.1] (5.74,6.1] (5.38,5.74] (5.74,6.1] (6.46,6.82] (6.1,6.46] (5.38,5.74] (5.38,5.74] [91] (5.38,5.74] (5.74,6.1] (5.74,6.1] (4.66,5.02] (5.38,5.74] (5.38,5.74] (5.38,5.74] (6.1,6.46] (5.02,5.38] (5.38,5.74] [101] (6.1,6.46] (5.74,6.1] (6.82,7.18] (6.1,6.46] (6.46,6.82] (7.54,7.9] (4.66,5.02] (7.18,7.54] (6.46,6.82] (7.18,7.54] [111] (6.46,6.82] (6.1,6.46] (6.46,6.82] (5.38,5.74] (5.74,6.1] (6.1,6.46] (6.46,6.82] (7.54,7.9] (7.54,7.9] (5.74,6.1] [121] (6.82,7.18] (5.38,5.74] (7.54,7.9] (6.1,6.46] (6.46,6.82] (7.18,7.54] (6.1,6.46] (5.74,6.1] (6.1,6.46] (7.18,7.54] [131] (7.18,7.54] (7.54,7.9] (6.1,6.46] (6.1,6.46] (5.74,6.1] (7.54,7.9] (6.1,6.46] (6.1,6.46] (5.74,6.1] (6.82,7.18] [141] (6.46,6.82] (6.82,7.18] (5.74,6.1] (6.46,6.82] (6.46,6.82] (6.46,6.82] (6.1,6.46] (6.46,6.82] (6.1,6.46] (5.74,6.1] 10 Levels: (4.3,4.66] (4.66,5.02] (5.02,5.38] (5.38,5.74] (5.74,6.1] (6.1,6.46] (6.46,6.82] (6.82,7.18] ... (7.54,7.9]
sumber
Trik lain. Beberapa paket, seperti glmnet, hanya menerima matriks desain dan variabel respons sebagai masukan. Jika seseorang ingin menyesuaikan model dengan semua interaksi antara fitur, dia tidak dapat menggunakan rumus "y ~. ^ 2". Menggunakan
expand.grid()
memungkinkan kita untuk memanfaatkan pengindeksan array yang kuat dan operasi vektor R.interArray=function(X){ n=ncol(X) ind=expand.grid(1:n,1:n) return(X[,ind[,1]]*X[,ind[,2]]) } > X X1 X2 1 0.96852363 0.33827107 2 0.08012755 0.69159828 3 0.10167545 0.38119304 4 0.06699458 0.41756415 5 0.08187816 0.09805104 > interArray(X) X1 X2 X1.1 X2.1 1 0.938038022 0.327623524 0.327623524 0.114427316 2 0.006420424 0.055416073 0.055416073 0.478308177 3 0.010337897 0.038757974 0.038757974 0.145308137 4 0.004488274 0.027974536 0.027974536 0.174359821 5 0.006704033 0.008028239 0.008028239 0.009614007
sumber
model.matrix
?Salah satu trik favorit saya, jika bukan merupakan trik ortodoks, adalah penggunaan
eval()
danparse()
. Contoh ini mungkin menggambarkan bagaimana itu dapat membantuNY.Capital <- 'Albany' state <- 'NY' parameter <- 'Capital' eval(parse(text=paste(state, parameter, sep='.'))) [1] "Albany"
Jenis situasi ini terjadi lebih sering daripada tidak, dan penggunaan
eval()
danparse()
dapat membantu mengatasinya. Tentu saja, saya menyambut baik umpan balik tentang cara alternatif pengkodean ini.sumber
set.seed()
mengatur status generator nomor acak.Sebagai contoh:
> set.seed(123) > rnorm(1) [1] -0.5604756 > rnorm(1) [1] -0.2301775 > set.seed(123) > rnorm(1) [1] -0.5604756
sumber
Bagi mereka yang menulis C untuk dipanggil dari R:
.Internal(inspect(...))
sangat berguna. Sebagai contoh:> .Internal(inspect(quote(a+2))) @867dc28 06 LANGSXP g0c0 [] @8436998 01 SYMSXP g1c0 [MARK,gp=0x4000] "+" @85768b0 01 SYMSXP g1c0 [MARK,NAM(2)] "a" @8d7bf48 14 REALSXP g0c1 [] (len=1, tl=0) 2
sumber
d = '~ / Kode R / Perpustakaan /'
files = list.files (d, '. r $')
untuk (f dalam file) {if (! (f == 'mysource.r')) {print (paste ('Sourcing', f)) source (paste (d, f, sep = ''))}}
Saya menggunakan kode di atas untuk sumber semua file dalam direktori saat memulai dengan berbagai program utilitas yang saya gunakan dalam sesi interaktif saya dengan R. Saya yakin ada cara yang lebih baik tetapi saya merasa berguna untuk pekerjaan saya. Garis yang melakukan ini adalah sebagai berikut.
sumber ("~ / R Code / Library / mysource.r")
sumber
Untuk melakukan operasi pada sejumlah variabel dalam bingkai data. Ini dicuri dari subset.data.frame.
get.vars<-function(vars,data){ nl <- as.list(1L:ncol(data)) names(nl) <- names(data) vars <- eval(substitute(vars), nl, parent.frame()) data[,vars] #do stuff here } get.vars(c(cyl:hwy,class),mpg)
sumber
get.vars
tanpa melewati banyak rintangan.Saya telah memposting ini sekali sebelumnya tetapi saya sering menggunakannya sehingga saya pikir saya akan mempostingnya lagi. Ini hanya sedikit fungsinya untuk mengembalikan nama dan nomor posisi dari data.frame. Tidak ada yang istimewa untuk memastikannya, tetapi saya hampir tidak pernah berhasil melewati sesi tanpa menggunakannya beberapa kali.
##creates an object from a data.frame listing the column names and location
namesind = fungsi (df) {
temp1=names(df) temp2=seq(1,length(temp1)) temp3=data.frame(temp1,temp2) names(temp3)=c("VAR","COL") return(temp3) rm(temp1,temp2,temp3)
}
ni <- namesind
sumber
data.frame(VAR = names(df), COL = seq_along(df))