Выберите случайные последовательные строки в группе

У меня есть данные, сгруппированные по 'student_id':

my_data = data.frame(student_id = c(1,1,1,1,1,2,2,2,2,2,3,3,3,3,3),
                     exam_no = c(1,2,3,4,5,1,2,3,4,5,1,2,3,4,5),
                     result = rnorm(15,60,10))


my_data
   student_id exam_no   result
1           1       1 56.60374
2           1       2 55.76655
3           1       3 53.81728
4           1       4 74.82202
5           1       5 34.91834
6           2       1 58.32422
7           2       2 60.38213
8           2       3 49.40390
9           2       4 63.85426
10          2       5 40.32912
11          3       1 69.54969
12          3       2 43.36639
13          3       3 37.97265
14          3       4 52.36436
15          3       5 61.62080

Мой вопрос:

Для каждого ученика я хочу выбрать набор последовательных строк со случайными начальными и конечными строками.

Например, сохранить экзамены 2–4 для учащегося 1, сохранить экзамены 2–5 для учащегося 2 и т. д.


Я подумал о следующем способе сделать это:

Создайте фрейм данных, содержащий максимальное количество экзаменов, которые сдает каждый студент (в моей задаче каждый студент сдает одинаковое количество экзаменов, но в будущем это может быть иначе)

library(dplyr)
counts = my_data %>% group_by(student_id) %>% summarise(counts = n())

# create variables that indicate where to start ("min") and where to end ("max") for each student
counts$min = sample(1:counts$counts, 1)
counts$max = sample(counts$min:counts$counts,1)

Отсюда я собирался написать цикл, который выбирал бы строки между «минимальным» и «максимальным» индексом для каждого ученика (например, my_data[min:max]), но результаты предыдущего кода дают мне предупреждения и нелогично Результаты:

Warning message:
In 1:counts$counts :
  numerical expression has 3 elements: only the first used

Warning messages:
1: In counts$min:counts$counts :
  numerical expression has 3 elements: only the first used
2: In counts$min:counts$counts :
  numerical expression has 3 elements: only the first used

# A tibble: 3 x 4
  student_id counts   min   max
       <dbl>  <int> <int> <int>
1          1      5     4     5
2          2      5     4     5
3          3      5     4     5

Я не уверен, как продолжить это - может кто-нибудь показать мне, как продолжить?

Спасибо!

Вам всегда нужно несколько строк на группу? Студент 1 имеет 5 рядов. В вашей попытке, если минимальная строка была 5 для учащегося 1, больше не осталось строк для выборки. Все хорошо? Или вам нужен метод, чтобы получить как минимум 2 строки на ученика? Какое распределение количества строк на одного ученика вы бы хотели? Если мы продолжим ваш метод — случайным образом выберем начальную и конечную строки — вы, как правило, выберете больше строк от студентов с большим количеством данных.

Gregor Thomas 19.02.2023 20:05

В качестве альтернативы вы можете сделать что-то вроде (а) выбора начальной строки, а затем (б) выбрать несколько строк для выборки из этой начальной строки. Это позволит вам легко сделать что-то вроде "выбрать 3, 4 или 5 случайных строк от каждого ученика" - хотя в зависимости от того, насколько вы обеспокоены предвзятостью, он может предпочесть более позднюю строку более ранним...

Gregor Thomas 19.02.2023 20:06

Связано: выберите две случайные и последовательные строки из сгруппированных данных (отказ от ответственности: я, по-видимому, также ответил на это... ;); выборка n случайно выбранных последовательных строк на всех уровнях фактора, но с фиксированным размером выборки.

Henrik 19.02.2023 20:37
Laravel с Turbo JS
Laravel с Turbo JS
Turbo - это библиотека JavaScript для упрощения создания быстрых и высокоинтерактивных веб-приложений. Она работает с помощью техники под названием...
Типы ввода HTML: Лучшие практики и советы
Типы ввода HTML: Лучшие практики и советы
HTML, или HyperText Markup Language , является стандартным языком разметки, используемым для создания веб-страниц. Типы ввода HTML - это различные...
Аутсорсинг разработки PHP для индивидуальных веб-решений
Аутсорсинг разработки PHP для индивидуальных веб-решений
Услуги PHP-разработки могут быть экономически эффективным решением для компаний, которые ищут высококачественные услуги веб-разработки по доступным...
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
Слишком много useState? Давайте useReducer!
Слишком много useState? Давайте useReducer!
Современный фронтенд похож на старую добрую веб-разработку, но с одной загвоздкой: страница в браузере так же сложна, как и бэкенд.
Узнайте, как использовать теги &lt;ul&gt; и &lt;li&gt; для создания неупорядоченных списков в HTML
Узнайте, как использовать теги <ul> и <li> для создания неупорядоченных списков в HTML
HTML предоставляет множество тегов для структурирования и организации содержимого веб-страницы. Одним из наиболее часто используемых тегов для...
4
3
64
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Базовый вариант R, использующий cumsum для обозначения промежуточных последовательных строк.

subset(
  my_data,
  ave(
    exam_no,
    student_id,
    FUN = function(x) cumsum(seq_along(x) %in% sample.int(length(x), 2))
  ) == 1
)

Что дает, например

   student_id exam_no   result
2           1       2 61.83643
3           1       3 51.64371
4           1       4 75.95281
6           2       1 51.79532
7           2       2 64.87429
8           2       3 67.38325
11          3       1 75.11781
12          3       2 63.89843
13          3       3 53.78759

Более компактная версия от data.table с той же идеей, что и выше.

library(data.table)
setDT(my_data)[, .SD[cumsum((1:.N) %in% sample.int(.N, 2)) == 1], student_id]
Ответ принят как подходящий

Используя data.table, в каждой группе выберите два значения из .I (без замены) и создайте последовательность индексов.

library(data.table)
setDT(my_data)

set.seed(3)
my_data[my_data[ , {ix = sample(.I, 2); ix[1]:ix[2]}, by = student_id]$V1]

#   student_id exam_no   result
#         <num>   <num>    <num>
# 1:          1       5 74.05672
# 2:          1       4 49.37525
# 3:          1       3 67.41662
# 4:          1       2 67.64935
# 5:          2       4 55.15337
# 6:          2       3 58.95694
# 7:          3       4 50.79859
# 8:          3       3 53.66886
# 9:          3       2 47.01089

Другие вопросы по теме

Какой должна быть стратегия для создания полулогарифмической последовательности с помощью всего нескольких инструкций ассемблера?
Поиск всех совпадающих папок/файлов, соответствующих формату ггггммдд_ччммсс между двумя датами и временем в Ansible
Цикл в строках фреймов данных для создания другого фрейма данных
Есть ли способ подсчитать длину и количество повторяющихся элементов в строке?
Как одновременно анализировать последовательные шаблоны и выводить переменные из набора последовательностей?
Установка элемента массива с последовательностью. Запрошенный массив имеет неоднородную форму после 1 измерения. Обнаруженная форма была (18,) + неоднородная часть
Как сделать строки с данными перетаскиваемыми и сохранить последовательность номеров столбцов
У меня есть анимированная последовательность изображений, которая воспроизводится в цикле. Как подключить его к кнопке, которая переключается между воспроизведением и паузой?
Повторно использовать удаленные последовательности первичных ключей (BIGSERIAL) — нет UUID для сохранения хранилища
Массив, в котором все элементы одного типа, делает элемент соответствующим некоторому протоколу