Группировка значений в массиве строк, соответствующих критериям в R

У меня есть большой фрейм данных df1, в котором есть столбец Student со строковыми значениями для имени студента, Grades с числовыми значениями для оценок за экзамен. Другой фрейм данных df2 с тремя столбцами: Class числовым, From To в качестве диапазона оценок и Count, в котором суммируется количество учащихся с определенной оценкой между некоторым значением для определенного класса.

В качестве примера:

Stundent <- c("Mark", "Jhon", "Stuart", "Lillie", "Carl", "Jason", "Stewart","Jack")
Grades <- c(7,9,1,6,7,6,4,8)
df1 <- data.frame(Stundent,Grades)

Class <- c(101, 101, 201, 308, 507, 201, 507, 308)
from <- c(1,6,1,1,6,6,1,6)
to <- c(5,10,5,5,10,10,5,10)
Count <- c(0,2,1,0,1,1,1,2)
df2 <- data.frame(Class,from,to,Count)
df2 <- df2[order(df2$Class),]

И я ожидаю получить что-то вроде этого

Students <- c("","Mark, Jhon", "Stuart", "Lillie", "","Carl, Jason", "Stewart", "Jack")
df3 <- data.frame(df2, Students)

person Paulo Cecco    schedule 09.05.2020    source источник
comment
Не могли бы вы уточнить, в каком классе учатся ученики df1? Соответствует ли список имен в df1 точно df2, так что первые два имени в df1 должны относиться к классу 101 (первые 2 строки df2)?   -  person Ben    schedule 09.05.2020
comment
Как вы сопоставляете df1 и df2 ? Разве в df1 не должен быть еще один столбец с именем Class?   -  person Ronak Shah    schedule 09.05.2020


Ответы (2)


Это не совсем ясно. Вот версия цикла for. Основываясь на ожидаемом результате, это может быть «Stundent» из «df1», выделенных для каждой строки столбца «df2» «Студенты», сравнивая «Оценки» с «от», «до» в «df2» и количество выбранных «Stundent» ограничено значением «Count». После выбора «Stundent» он больше не повторяется.

tmpdat <- df1
tmpdat$Stundent <- as.character(tmpdat$Stundent)

df2$Students <- ""
for(i in seq_len(nrow(df2))) {

       if(df2$Count[i] >0 ) {
        st1 <- head(tmpdat$Stundent[tmpdat$Grades >= df2$from[i] & 
                                    tmpdat$Grades <= df2$to[i]], df2$Count[i])
        tmpdat <- tmpdat[!tmpdat$Stundent %in% st1, ]
        df2$Students[i] <- toString(st1) 

      }

  }




df2
#  Class from to Count    Students
#1   101    1  5     0            
#2   101    6 10     2  Mark, Jhon
#3   201    1  5     1      Stuart
#6   201    6 10     1      Lillie
#4   308    1  5     0            
#8   308    6 10     2 Carl, Jason
#5   507    6 10     1        Jack
#7   507    1  5     1     Stewart

В ожидаемом результате Джек и Стюарт для 507 поменялись местами. Начиная с df1, оценки Джека — 8, а Стюарта — 4.

person akrun    schedule 09.05.2020

Я предполагаю, что в df1 должен быть еще один столбец, который будет Class идентифицирующим, какой студент находится в каком Class, потому что нет информации, соответствующей данным. Если мое предположение неверно, дайте мне знать, и я удалю ответ.

#adding class column
df1$Class <- c(101, 101, 201, 201, 308, 308, 507, 507)

Мы можем left_join df1 и df2 с помощью Class и создать значения Stundent, разделенные запятыми, которые находятся в диапазоне.

library(dplyr)

df1 %>%
  left_join(df2, by = 'Class') %>%
  group_by(Class, from, to) %>%
  summarise(Stundent = toString(Stundent[Grades >= from & Grades <= to]))


#  Class  from    to Stundent     
#  <dbl> <dbl> <dbl> <chr>        
#1   101     1     5 ""           
#2   101     6    10 "Mark, Jhon" 
#3   201     1     5 "Stuart"     
#4   201     6    10 "Lillie"     
#5   308     1     5 ""           
#6   308     6    10 "Carl, Jason"
#7   507     1     5 "Stewart"    
#8   507     6    10 "Jack"      
person Ronak Shah    schedule 09.05.2020