Зразок випадкових рядків у кадрі даних


333

Я намагаюся знайти відповідну функцію, яка б повернула задану кількість рядків, зібраних випадковим чином, без заміни з кадру даних мовою R? Хтось може мені допомогти?

Відповіді:


445

Спочатку внесіть деякі дані:

> 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

Потім виберіть випадково кілька рядків:

> df[sample(nrow(df), 3), ]
           X1         X2
9  -0.3983045  0.7157506
2  -1.1334614 -0.1973846
10 -0.9060305  2.3234110

4
@nikhil Дивіться тут і тут для початку. Ви також можете ввести ?sampleконсоль R, щоб прочитати про цю функцію.
Joran

10
Чи може хтось пояснити, чому зразок (df, 3) не працює? Для чого вам потрібен df [sample (nrow (df), 3),]?
stackoverflowuser2010

5
@ stackoverflowuser2010, ви можете набрати? sample та побачити, що перший аргумент у функції вибірки повинен бути векторним чи додатним цілим числом. Я не думаю, що data.frame в цьому випадку працює як вектор.
Девід Браун

9
Не забудьте встановити насіння (наприклад set.seed(42)) щоразу, коли ви хочете відтворити цей конкретний зразок.
CousinCocaine

2
sample.intбуде трохи швидше, я вважаю:library(microbenchmark);microbenchmark( sample( 10000, 100 ), sample.int( 10000, 100 ), times = 10000 )
Арі Б. Фрідман

199

Відповідь, яку дає Джон Колбі, - це правильна відповідь. Однак якщо ви dplyrкористувач, є також відповідь sample_n:

sample_n(df, 10)

випадковим чином відбирає 10 рядків з фрейму даних. Він викликає дзвінки sample.int, тому насправді це одна і та ж відповідь з меншим типом (і спрощує використання в контексті magrittr, оскільки фрейм даних є першим аргументом).


33

Напишіть одну! Відповідь JC, що перегортає, дає мені:

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

Тепер краще зробити це, перевіривши спочатку, якщо n <= nrow (df), і зупинившись з помилкою.


33

data.tableПакет надає функцію DT[sample(.N, M)], вибірки М випадкових рядків з таблиці даних 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

10

Просто заради повноти:

dplyr також пропонує намалювати пропорцію або частку вибірки за

df %>% sample_frac(0.33)

Це дуже зручно, наприклад, при машинному навчанні, коли вам потрібно виконати певний коефіцієнт розділення, наприклад 80%: 20%


9

EDIT : Ця відповідь застаріла, дивіться оновлену версію .

У своєму пакеті R я вдосконалив, sampleтак що тепер він поводиться так, як очікувалося, і для кадрів даних:

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

Це досягається шляхом створення sampleзагального методу S3 та надання необхідної (тривіальної) функціональності функції. Заклик setMethodвиправити все. До оригінальної реалізації все ще можна отримати доступ base::sample.


1
Що несподіваного щодо обробки кадрів даних?
інший бен

2
@adifferentben: Коли я закликаю sample.default(df, ...)кадр даних df, він вибирає з стовпців кадру даних, оскільки кадр даних реалізований у вигляді списку векторів однакової довжини.
krlmlr

Ваш пакет все ще доступний? Я побіг install_github('kimisc', 'krlmlr')і дістався Error: Does not appear to be an R package (no DESCRIPTION). Як-небудь навколо цього?
тердон

1
@JorisMeys: Погоджено, за винятком частини "як очікувалося". Тільки тому, що кадр даних реалізований як список внутрішньо, це не означає, що він повинен вести себе як єдиний. [Оператор кадрів даних контрприклад. Також скажіть, будь ласка: Ви коли-небудь, лише один раз, використовували sampleдля вибірки стовпців із фрейму даних?
krlmlr

1
@krlmlr Оператор [не є контрприкладом: iris[2]працює як список, як і iris[[2]]. Або iris$Species, lapply(iris, mean)... Кадри даних списків. Тож я очікую, що вони поводяться як вони. І так, я фактично використовував зразок (myDataframe). На наборі даних, де кожна змінна містить дані експресії одного гена. Ваш конкретний метод допомагає початківцям користувачам, але також ефективно змінює спосіб sample()поведінки. Примітка Я використовую "як очікувалося" з точки зору програміста. Що відрізняється від загальної інтуїції. У R дуже багато, що не сумісне із загальною інтуїцією ...;)
Joris Meys

8

Застаріла відповідь. Будь ласка, використовуйте dplyr::sample_frac()або dplyr::sample_n()замість цього.

У моєму пакеті R є функція sample.rowsсаме для цієї мети:

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

Покращення sample, зробивши його загальною функцією S3, було поганою ідеєю, згідно з коментарями Йорзіс Мейс до попередньої відповіді .


5

Виберіть випадковий зразок із типу тиблизи в R:

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

nrow приймає таблицю і повертає кількість рядків. Перший переданий параметр sample- це діапазон від 1 до кінця таблиці. Другий параметр, переданий для вибірки, 150, - це кількість випадкових вибірок. Нарізка квадратної дужки вказує рядки повернених індексів. Змінна 'a' отримує значення випадкової вибірки.


3

Ви можете це зробити:

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

Нагорі я лише зробив кадр даних з 10 стовпцями та 100 рядками, добре?

Тепер ви можете спробувати його за допомогою 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

1

Я новачок в R, але я використовував цей простий метод, який працює для мене:

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

PS: Не соромтесь зауважувати, чи є у нього якийсь недолік, про який я не думаю.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.