Подмножество данных на основе значения в идентификаторах в r - PullRequest
1 голос
/ 10 января 2020

Я пытаюсь установить поднабор данных на основе двух критериев. Вот снимок моих данных:

ids <-  c(1,1,1,1,1,1, 2,2,2,2,2,2, 3,3,3,3,3,3)
seq <-  c(1,2,3,4,5,6, 1,2,3,4,5,6, 1,2,3,4,5,6)
type <- c(1,1,5,1,1,1, 1,1,1,8,1,1, 1,1,1,1,1,1)
    data <- data.frame(ids, seq, type)

   ids seq type
1    1   1    1
2    1   2    1
3    1   3    5
4    1   4    1
5    1   5    1
6    1   6    1
7    2   1    1
8    2   2    1
9    2   3    1
10   2   4    8
11   2   5    1
12   2   6    1
13   3   1    1
14   3   2    1
15   3   3    1
16   3   4    1
17   3   5    1
18   3   6    1

ids - идентификатор студента, seq - последовательность вопросов (предметов), которые учащиеся принимают. type относится к типу вопроса. 1 просто, 5 или 8 - сложные предметы. Я хотел бы создать 1-ю переменную (complex) относительно того, есть ли у ученика сложный предмет (type=5|8). Тогда я хотел бы получить:

   > data
   ids seq type complex
1    1   1    1       1
2    1   2    1       1
3    1   3    5       1
4    1   4    1       1
5    1   5    1       1
6    1   6    1       1
7    2   1    1       1
8    2   2    1       1
9    2   3    1       1
10   2   4    8       1
11   2   5    1       1
12   2   6    1       1
13   3   1    1       0
14   3   2    1       0
15   3   3    1       0
16   3   4    1       0
17   3   5    1       0
18   3   6    1       0

Второй шаг - разделить данные внутри студентов. (a) Для студента, у которого есть не сложные предметы (complex=0), я хотел бы разделить набор данных на половину и получить это ниже:

>simple.split.1
    ids seq type   complex
13   3   1    1       0
14   3   2    1       0
15   3   3    1       0

>simple.split.2
    ids seq type   complex
16   3   4    1       0
17   3   5    1       0
18   3   6    1       0

(b) для студентов, которые имеют сложные элементы (complex=1), я хотел бы установить сложный элемент как точку обрезки и разделить данные оттуда. Таким образом, данные должны выглядеть следующим образом (исключая сложный элемент):

   >complex.split.1
    ids seq type   complex
1    1   1    1       1
2    1   2    1       1
7    2   1    1       1
8    2   2    1       1
9    2   3    1       1

    >complex.split.2
    ids seq type   complex
4    1   4    1       1
5    1   5    1       1
6    1   6    1       1
11   2   5    1       1
12   2   6    1       1

Есть мысли? Спасибо

Ответы [ 2 ]

3 голосов
/ 10 января 2020

Вот способ сделать это, используя data.table, zoo пакеты и split функцию:

library(data.table)
library(zoo)

setDT(data)[, complex := ifelse(type == 5 | type == 8, 1, NA_integer_), by = ids][, complex := na.locf(na.locf(complex, na.rm=FALSE), na.rm=FALSE, fromLast=TRUE), by = ids][, complex := ifelse(is.na(complex), 0, complex)] ## set data to data.table & add a flag 1 where type is 5 or 8 ## carry forward and backward of complex flag ## replace na values in complex column with 0

data <- data[!(type == 5 | type == 8), ] ## removing rows where type equals 5 or 8

complex <- split(data, data$complex) ## split data based on complex flag

complex_0 <- as.data.frame(complex$`0`) ## saving as data frame based on complex flag
complex_1 <- as.data.frame(complex$`1`)

split(complex_0, cut(complex_0$seq, 2)) ## split into equal parts
split(complex_1, cut(complex_1$seq, 2))


#$`(0.995,3.5]`
#   ids seq type complex
#1   3   1    1       0
#2   3   2    1       0
#3   3   3    1       0

#$`(3.5,6]`
#   ids seq type complex
#4   3   4    1       0
#5   3   5    1       0
#6   3   6    1       0



    #$`(0.995,3.5]`
#   ids seq type complex
#1   1   1    1       1
#2   1   2    1       1
#6   2   1    1       1
#7   2   2    1       1
#8   2   3    1       1

#$`(3.5,6]`
#    ids seq type complex
#3    1   4    1       1
#4    1   5    1       1
#5    1   6    1       1
#9    2   5    1       1
#10   2   6    1       1
2 голосов
/ 10 января 2020

Если вы предпочитаете использовать tidyverse, вот подход:

ids <-  c(1,1,1,1,1,1, 2,2,2,2,2,2, 3,3,3,3,3,3)
seq <-  c(1,2,3,4,5,6, 1,2,3,4,5,6, 1,2,3,4,5,6)
type <- c(1,1,5,1,1,1, 1,1,1,8,1,1, 1,1,1,1,1,1)
data <- data.frame(ids, seq, type)

step1.data <- data %>%
  group_by(ids) %>%
  mutate(complex = ifelse(any(type %in% c(5,8)), 1, 0)) %>%
  ungroup()

simple.split.1 <- step1.data %>%
  filter(complex == 0) %>%
  group_by(ids) %>%
  filter(seq <= mean(seq)) %>% #if you happen to have more than 6 questions in seq, this gives the midpoint
  ungroup()

simple.split.2 <- step1.data %>%
  filter(complex == 0) %>%
  group_by(ids) %>%
  filter(seq > mean(seq)) %>%
  ungroup()

complex.split.1 <- step1.data %>%
  filter(complex == 1) %>%
  arrange(ids, seq) %>%
  group_by(ids) %>%
  filter(seq < min(seq[type %in% c(5,8)])) %>%
  ungroup()

complex.split.2 <- step1.data %>%
  filter(complex == 1) %>%
  arrange(ids, seq) %>%
  group_by(ids) %>%
  filter(seq > min(seq[type %in% c(5,8)])) %>%
  ungroup()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...