Я пытаюсь заполнить фрейм данных результатом цикла for, но мне чего-то не хватает. Я смотрел на прошлые вопросы по этому поводу, но я не могу разобраться с решением, так что ...

Вымышленные данные:

df <- data.frame(RA = c(rep("14005", 3), rep("14158", 3), rep("15458", 2), rep("15302", 2)),
             Level = c(rep("Grad", 6), rep("Undergrad", 4)),
             EntryYear = c(rep(2014, 6), rep(2015, 4)),
             ExitYear = c(rep(2016, 3), rep(2017, 3), rep(2018, 4)))

Я хочу заполнить фрейм данных результатом конкретного конвейера dplyr:

df %>% 
filter(Level == "Grad", EntryYear <= year, ExitYear >= year) %>% 
distinct(RA) %>% 
summarise(year = n())

Где год - это конкретный год, который меня интересует (по моим исходным данным, он идет с 2010 по 2017 год). Приведенная выше формула предназначена для приблизительного расчета количества студентов, зарегистрированных в данном году. [Я буду использовать еще две формулы для подсчета количества выпускников и первокурсников, поэтому у меня будет еще две строки / столбца]. А также:

start.year <- 2010
end.year <- 2017

Итак, я сделал этот цикл for, чтобы увидеть, работает ли он:

for (year in start.year:end.year){
  mat <- df %>% 
    filter(Level == "Grad", EntryYear <= year, ExitYear >= year) %>% 
    distinct(RA) %>% 
    summarise(year= n())
  print(mat)
}

Он печатает то, что я хочу, но тогда я не могу записать это в кадр данных ... Ожидаемый результат - это кадр данных с 7 строками. Результат final представляет собой фрейм данных с 7 строками и 3 столбцами (две другие формулы / конвейеры, которые я буду применять).

1
GVianaF 26 Фев 2018 в 23:50

5 ответов

Лучший ответ

Поскольку вы уже используете dplyr, вы также можете легко использовать purrr для объединения данных.

library(purrr)
map_df(start.year:end.year, function(year) {
  mat <- df %>% 
    filter(Level == "Grad" & EntryYear <= year & ExitYear >= year) %>% 
    distinct(RA) %>% 
    summarise(year= n())
})
6
A J 26 Фев 2018 в 21:46

Просто добавьте эти две строки в ваш окончательный код:

new_df <- data.frame(). # <- this one
for (year in start.year:end.year){
    mat <- df %>% 
        filter(Level == "Grad", EntryYear <= year, ExitYear >= year) %>% 
        distinct(RA) %>% 
        summarise(year= n())
    new_df <- rbind(new_df, mat) # <- this one
}
1
YOLO 26 Фев 2018 в 21:07
for (year in start.year:end.year){
  mat <- df %>% 
    filter(Level == "Grad", EntryYear <= year, ExitYear >= year) %>% 
    distinct(RA) %>% 
    summarise(year= n())
  print(mat)

  if (year<2011){

    final <- as.data.frame(mat)

  }

  else{

    final <- rbind(final,as.data.frame(mat))

  }
}
0
P__2 26 Фев 2018 в 21:00
# load packages
library(plyr)
library(dplyr)

# Filter function
filterdf<-function(year, level){
  mat <- df %>% 
    filter(Level == level, EntryYear <= year, ExitYear >= year) %>% 
    distinct(RA) %>% 
    summarise(year= n())
  colnames(mat)<-paste0(level, "_number")
  return(mat)
}

# Create your input conditions
input<-as.data.frame(seq(2010,2017))
colnames(input)<-"year"
input$level<-"Grad"

# Output to a dataframe
output<-mdply(input,filterdf)
0
Marko 26 Фев 2018 в 21:19

Вот tidyverse альтернатива:

library(tidyverse)
df %>%
  filter(Level=="Grad") %>%
  mutate(year = map2(EntryYear,ExitYear,~.x:.y)) %>%
  unnest(year) %>%
  distinct(RA,year) %>%
  count(year)

# # A tibble: 4 x 2
#    year     n
#   <int> <int>
# 1  2014     2
# 2  2015     2
# 3  2016     2
# 4  2017     1
0
Moody_Mudskipper 5 Мар 2018 в 01:39