Contoh baris acak dalam bingkai data

333

Saya kesulitan menemukan fungsi yang sesuai yang akan mengembalikan jumlah baris tertentu yang diambil secara acak tanpa penggantian dari bingkai data dalam bahasa R? Adakah yang bisa membantu saya?

nikhil
sumber

Jawaban:

445

Pertama-tama buat beberapa data:

> df = data.frame(matrix(rnorm(20), nrow=10))
> df
           X1         X2
1   0.7091409 -1.4061361
2  -1.1334614 -0.1973846
3   2.3343391 -0.4385071
4  -0.9040278 -0.6593677
5   0.4180331 -1.2592415
6   0.7572246 -0.5463655
7  -0.8996483  0.4231117
8  -1.0356774 -0.1640883
9  -0.3983045  0.7157506
10 -0.9060305  2.3234110

Kemudian pilih beberapa baris secara acak:

> df[sample(nrow(df), 3), ]
           X1         X2
9  -0.3983045  0.7157506
2  -1.1334614 -0.1973846
10 -0.9060305  2.3234110
John Colby
sumber
4
@nikhil Lihat di sini dan di sini untuk pemula. Anda juga dapat mengetik ?sampledi konsol R untuk membaca tentang fungsi itu.
joran
10
Adakah yang bisa menjelaskan mengapa sampel (df, 3) tidak berfungsi? Mengapa Anda perlu df [sampel (nrow (df), 3),]?
stackoverflowuser2010
5
@ stackoverflowuser2010, Anda dapat mengetik? Sampel dan melihat bahwa argumen pertama dalam fungsi sampel harus berupa vektor atau bilangan bulat positif. Saya tidak berpikir data.frame berfungsi sebagai vektor dalam hal ini.
David Braun
9
Ingatlah untuk mengatur benih Anda (mis. set.seed(42)) Setiap kali Anda ingin mereproduksi sampel spesifik itu.
CousinCocaine
2
sample.intakan sedikit lebih cepat saya percaya:library(microbenchmark);microbenchmark( sample( 10000, 100 ), sample.int( 10000, 100 ), times = 10000 )
Ari B. Friedman
199

Jawaban yang diberikan John Colby adalah jawaban yang tepat. Namun jika Anda seorang dplyrpengguna, ada juga jawabannya sample_n:

sample_n(df, 10)

secara acak sampel 10 baris dari kerangka data. Itu panggilan sample.int, jadi benar-benar adalah jawaban yang sama dengan kurang mengetik (dan menyederhanakan penggunaan dalam konteks magrittr karena dataframe adalah argumen pertama).

kasterma
sumber
33

Tulis satu! Membungkus jawaban JC memberi saya:

randomRows = function(df,n){
   return(df[sample(nrow(df),n),])
}

Sekarang buat lebih baik dengan memeriksa dulu apakah n <= nrow (df) dan berhenti dengan kesalahan.

Spacedman
sumber
33

The data.tablepaket menyediakan fungsi DT[sample(.N, M)], sampling M baris acak dari tabel data DT.

library(data.table)
set.seed(10)

mtcars <- data.table(mtcars)
mtcars[sample(.N, 6)]

    mpg cyl  disp  hp drat    wt  qsec vs am gear carb
1: 14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
2: 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
3: 17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
4: 21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
5: 22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
6: 15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
Gented
sumber
10

Demi kelengkapan saja:

dplyr juga menawarkan untuk menggambar proporsi atau fraksi sampel dengan

df %>% sample_frac(0.33)

Ini sangat mudah misalnya dalam pembelajaran mesin ketika Anda harus melakukan rasio split tertentu seperti 80%: 20%

Kacang Agile
sumber
9

EDIT : Jawaban ini sekarang sudah usang, lihat versi yang diperbarui .

Dalam paket R saya, saya telah meningkatkan samplesehingga sekarang berperilaku seperti yang diharapkan juga untuk bingkai data:

library(devtools); install_github('kimisc', 'krlmlr')

library(kimisc)
example(sample.data.frame)

smpl..> set.seed(42)

smpl..> sample(data.frame(a=c(1,2,3), b=c(4,5,6),
                           row.names=c('a', 'b', 'c')), 10, replace=TRUE)
    a b
c   3 6
c.1 3 6
a   1 4
c.2 3 6
b   2 5
b.1 2 5
c.3 3 6
a.1 1 4
b.2 2 5
c.4 3 6

Ini dicapai dengan membuat samplemetode generik S3 dan menyediakan fungsionalitas (sepele) yang diperlukan dalam suatu fungsi. Panggilan untuk setMethodmemperbaiki semuanya. Implementasi asli masih dapat diakses melalui base::sample.

krlmlr
sumber
1
Apa yang tidak terduga tentang perlakuannya terhadap frame data?
berbeda ben
2
@ adifferentben: Ketika saya memanggil sample.default(df, ...)frame data df, sampel dari kolom frame data, sebagai frame data diimplementasikan sebagai daftar vektor dengan panjang yang sama.
krlmlr
Apakah paket Anda masih tersedia? Aku berlari install_github('kimisc', 'krlmlr')dan berlari Error: Does not appear to be an R package (no DESCRIPTION). Ada jalan lain?
terdon
1
@ JorisMeys: Setuju, kecuali untuk bagian "seperti yang diharapkan". Hanya karena bingkai data diimplementasikan sebagai daftar secara internal, itu tidak berarti itu harus berperilaku sebagai satu. The [Operator untuk frame data counterexample. Juga, tolong beri tahu saya: Apakah Anda pernah, hanya sekali saja, digunakan sampleuntuk mengambil sampel kolom dari bingkai data?
krlmlr
1
@ krlmlr [Operator bukan contoh balasan: iris[2]berfungsi seperti daftar, seperti halnya iris[[2]]. Atau iris$Species,, lapply(iris, mean)... Frame data adalah daftar. Jadi saya berharap mereka berperilaku seperti mereka. Dan ya, saya sudah menggunakan sampel (myDataframe). Pada dataset di mana setiap variabel berisi data ekspresi gen tunggal. Metode spesifik Anda membantu pengguna pemula, tetapi juga secara efektif mengubah cara sample()berperilaku. Catatan saya menggunakan "seperti yang diharapkan" dari pandangan programmer. Yang berbeda dengan intuisi umum. Ada banyak hal dalam R yang tidak kompatibel dengan intuisi umum ...;)
Joris Meys
8

Jawaban yang ketinggalan jaman. Silakan gunakan dplyr::sample_frac()atau dplyr::sample_n()sebagai gantinya.

Dalam paket R saya ada fungsi sample.rowshanya untuk tujuan ini:

install.packages('kimisc')

library(kimisc)
example(sample.rows)

smpl..> set.seed(42)

smpl..> sample.rows(data.frame(a=c(1,2,3), b=c(4,5,6),
                               row.names=c('a', 'b', 'c')), 10, replace=TRUE)
    a b
c   3 6
c.1 3 6
a   1 4
c.2 3 6
b   2 5
b.1 2 5
c.3 3 6
a.1 1 4
b.2 2 5
c.4 3 6

Meningkatkan sampledengan menjadikannya fungsi S3 generik adalah ide yang buruk, menurut komentar Joris Meys untuk jawaban sebelumnya .

krlmlr
sumber
5

Pilih sampel acak dari jenis tibble di R:

library("tibble")    
a <- your_tibble[sample(1:nrow(your_tibble), 150),]

nrow mengambil tibble dan mengembalikan jumlah baris. Parameter pertama yang diteruskan sampleadalah rentang dari 1 hingga akhir tibble Anda. Parameter kedua yang diteruskan ke sampel, 150, adalah berapa banyak sampel acak yang Anda inginkan. Mengiris braket persegi menentukan baris indeks yang dikembalikan. Variabel 'a' mendapat nilai dari random sampling.

Eric Leschinski
sumber
3

Anda bisa melakukan ini:

library(dplyr)

cols <- paste0("a", 1:10)
tab <- matrix(1:1000, nrow = 100) %>% as.tibble() %>% set_names(cols)
tab
# A tibble: 100 x 10
      a1    a2    a3    a4    a5    a6    a7    a8    a9   a10
   <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
 1     1   101   201   301   401   501   601   701   801   901
 2     2   102   202   302   402   502   602   702   802   902
 3     3   103   203   303   403   503   603   703   803   903
 4     4   104   204   304   404   504   604   704   804   904
 5     5   105   205   305   405   505   605   705   805   905
 6     6   106   206   306   406   506   606   706   806   906
 7     7   107   207   307   407   507   607   707   807   907
 8     8   108   208   308   408   508   608   708   808   908
 9     9   109   209   309   409   509   609   709   809   909
10    10   110   210   310   410   510   610   710   810   910
# ... with 90 more rows

Di atas saya baru saja membuat bingkai data dengan 10 kolom dan 100 baris, ok?

Sekarang Anda dapat mencicipi dengan sample_n:

sample_n(tab, size = 800, replace = T)
# A tibble: 800 x 10
      a1    a2    a3    a4    a5    a6    a7    a8    a9   a10
   <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
 1    53   153   253   353   453   553   653   753   853   953
 2    14   114   214   314   414   514   614   714   814   914
 3    10   110   210   310   410   510   610   710   810   910
 4    70   170   270   370   470   570   670   770   870   970
 5    36   136   236   336   436   536   636   736   836   936
 6    77   177   277   377   477   577   677   777   877   977
 7    13   113   213   313   413   513   613   713   813   913
 8    58   158   258   358   458   558   658   758   858   958
 9    29   129   229   329   429   529   629   729   829   929
10     3   103   203   303   403   503   603   703   803   903
# ... with 790 more rows
igorkf
sumber
1

Saya baru di R, tapi saya menggunakan metode mudah ini yang berfungsi untuk saya:

sample_of_diamonds <- diamonds[sample(nrow(diamonds),100),]

PS: Jangan ragu untuk mencatat jika ada kekurangan yang tidak saya pikirkan.

Leopoldo Sanczyk
sumber
0

Anda bisa melakukan ini:

sample_data = data[sample(nrow(data), sample_size, replace = FALSE), ]
Mohammad
sumber