R - 总结相对学期顺序的课程注册

问题描述 投票:3回答:1

应用问题

我想抽象出代码,总结课程学习模式和n个课程和n个学期的一群学生的成功率。

通过以下队列的学生,在参加“A”课程后,有多少人去了“B”课程,有多少学生成功了:

data <- data.frame(student = c(1, 1, 1, 2, 2, 2, 3, 4, 4, 5, 5, 5),
                   term    = c(2, 3, 3, 1, 2, 3, 2, 1, 3, 1, 2, 4),
                   course  = c('A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'A', 'C'),
                   success = c(1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1),
                   stringsAsFactors = FALSE)

我们可以使用以下代码回答这个问题:

library(dplyr) 

# Get each student's first, second, third, ... term.
    data <- data %>%
      group_by(student) %>%
      mutate(term_dense = dense_rank(term))%>%
      ungroup()

# Identify those who took course A
    courseA <- data %>%
      filter(course == "A")%>%
      select(student, courseA_dense = term_dense)

# Get records of students who took course A, and their subsequent courses
    data <- data %>%
      left_join(courseA, by = "student")%>%
      filter(term_dense >= courseA_dense) # >= for courses they took in same term as course "A"

# Summarise for each term_dense
    data %>%
      group_by(term_dense) %>%
      summarise(attempted_course_A = sum(course == "A"),
                completed_course_A = sum(course == "A" & success == 1),
                attempted_course_B = sum(course == "B"),
                completed_course_B = sum(course == "B" & success == 1))

哪个产生:

# A tibble: 3 x 5
  term_dense attempted_course_A completed_course_A attempted_course_B completed_course_B
       <int>              <int>              <int>              <int>              <int>
1          1                  4                  2                  0                  0
2          2                  2                  2                  2                  2
3          3                  0                  0                  0                  0

我们可以看到那些尝试过A课程的学生,那两个尝试过课程B,两个都成功了。

现在,我可以通过在summarise声明(即completed_course_C = sum(course == "C" & success == 1))中添加线来计算课程“A”之后有多少课程“C”,但如果我有很多课程,那么它似乎不是最有效的选择。

此外,如果我想在课程“Y”之后总结课程“X”的顺序,对于任何“X”和“Y”,它会创建更多summarise语句的排列。我如何看待那些在“Z”之后的“Y”之后取“X”的人。

那么,如何在不同数量的条款下总结不同数量的课程的课程进度和成功率?

期望的输出

我认为这是我的一些困难所在。我不知道结果data.frame需要结构如何。

我知道我想轻松回答以下一般问题:

“X%的学生在课程中获得成功”A“,随后选修课程”B“,成功率为Y%”

抽象问题

我一直在尝试将一般问题(群组跟踪/排序?)应用到其他字段,以便在google和Stack Overflow中获得更好的关键词/搜索结果。一个似乎很有希望的是使用网络分析。

具体而言,this post, Network Analysis with R有助于确定潜在的解决方案。我按照这篇文章,使用我的数据,然后能够获得大约一半的信息。使用这种方法,我只能获得一系列尝试或一系列成功率 - 而不是两者兼而有之。但我刚开始学习网络分析。

实际上,我已经能够使用plotly's sankey diagram手动可视化摘要,purrr使用类似的网络/链接框架。但我仍然无法以编程方式计算该信息。

其他尝试

鉴于我想基本上将汇总函数“映射”到我的数据,我的许多尝试都使用了带有嵌套列表列的purrr包。

data attempts

使用上面的原始# library(dplyr) # Loaded in above example library(tidyr) library(purrr) data <- data %>% group_by(student) %>% mutate(term_dense = dense_rank(term)) %>% ungroup()%>% nest(term, course, success, .key = "schedule") ,我试图根据他们的排名术语列出学生的课程列表。

map

然后我尝试创建一个函数,将源课程的摘要返回到目标课程,最终目标是将attempt_summary <- function(df, source, target){ temp_df <- df %>% filter(map_lgl(schedule, ~any(.x$course == source)))%>% select(student, source_term_dense = term_dense) df <- df %>% left_join(temp_df, by = "student")%>% filter(term_dense >= source_term_dense) df %>% group_by(term_dense) %>% summarise(completed_source = sum(map_int(schedule, ~any(.x$course == source & .x$success == 1))), attempted_target = sum(map_int(schedule, ~any(.x$course == target))), completed_target = sum(map_int(schedule, ~any(.x$course == target & .x$success == 1)))) } 此函数添加到包含源和目标的所有唯一排列的列表中:

attempt_summary(data, "A", "B")

# A tibble: 3 x 4
  term_dense completed_source attempted_target completed_target
       <int>            <int>            <int>            <int>
1          1                2                0                0
2          2                2                2                2
3          3                0                0                0

该功能适用​​于一个例子,

# DO NOT RUN - DOESN'T WORK
# map(data, attempt_summary, source = src_list, target = trgt_list)

但我无法弄清楚如何将它映射到其他一切(我甚至无法弄清楚如何构建我的目标和源列表)但这是我的尝试:

purrr

Stack Overflow Posts

除了关于Tracking cohort over time in R的许多其他人之外,我在寻找解决方案时引用了这些帖子,但没有一个是我想要的。

会话信息

这是我的> sessionInfo() R version 3.5.3 (2019-03-11) Platform: x86_64-w64-mingw32/x64 (64-bit) Running under: Windows 10 x64 (build 17763) Matrix products: default locale: [1] LC_COLLATE=English_United States.1252 LC_CTYPE=English_United States.1252 [3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C [5] LC_TIME=English_United States.1252 attached base packages: [1] stats graphics grDevices utils datasets methods base other attached packages: [1] purrr_0.3.2 tidyr_0.8.3 dplyr_0.8.0.1 loaded via a namespace (and not attached): [1] Rcpp_1.0.1 fansi_0.4.0 utf8_1.1.4 crayon_1.3.4 assertthat_0.2.1 R6_2.4.0 [7] magrittr_1.5 pillar_1.3.1 cli_1.1.0 rlang_0.3.4 rstudioapi_0.10 tools_3.5.3 [13] glue_1.3.1 compiler_3.5.3 pkgconfig_2.0.2 tidyselect_0.2.5 tibble_2.1.1 电话的输出:

library(tidyverse)
data2 <- data %>%
  left_join(data, by = c("student")) %>%   # add future course results to each result that has any
  filter(term.y > term.x) %>%  # includes all future courses; could limit to just next one?
  count(course.x, success.x, course.y, success.y) %>%
  spread(success.y, n, fill = 0) %>%
  mutate(success_rate = `1`/ (`0` + `1`)) %>%
  select(course.x:course.y, success_rate) %>%
  spread(course.y, success_rate)
r dplyr sequence purrr
1个回答
0
投票

这里有一个关于你的问题的中间部分关于“X%的学生在课程中取得成功”A“,随后选修课程”B“并且成功率为Y%”。

这会找到每个课程成功的Y%,并且每个课程A都不成功。

> data2
# A tibble: 3 x 5
  course.x success.x     A     B     C
  <chr>        <dbl> <dbl> <dbl> <dbl>
1 A                0     1    NA   1  
2 A                1    NA     1   1  
3 B                1    NA    NA   0.5

结果:每个“事件1”作为一行,并且每列中的未来类Y的成功率。这表明服用A的人通过了所有后续课程,无论他们在A中如何做。服用B的人在C上的通过率为50-50。

qazxswpoi
© www.soinside.com 2019 - 2024. All rights reserved.