R语言 如何识别组中最常见的值组合?

elcex8rz  于 12个月前  发布在  其他
关注(0)|答案(4)|浏览(133)

我有一个表,其中每行代表一个学生在一门课程中的注册情况,与此类似,但要大得多:
| 学生|当然|
| --|--|
| 001 |PSYC101|
| 001 |CHEM102|
| 002 |PSYC101|
| 002 |公司简介|
| 002 |BIO101|
| 003 |BIO101|
| 003 |ENG201|
| 003 |HIND101|
| 003 |CHEM102|
| 004 |PSYC101|
| 004 |CHEM102|
| 004 |HIND101|
我想知道学生最常一起学习的课程组合。我从两门课程的组合开始,但也可能想看看三门课程的组合。
我完全不知道这个手术叫什么。
我发现了这个类似的例子,它使用了dplyr包:https://stackoverflow.com/questions/61613192/r-how-to-find-the-most-frequent-combinations
然而,我不认为这正是我想要的。我想要所有可能的2门课程的组合,当一些学生已经采取了2门以上的课程。例如,对于学生3,他们将有以下内容:

  • BIO101 & ENG201
  • BIO 101和HIND 101
  • BIO 101和CHEM 102
  • ENG201 & HIND101
  • ENG201 & CHEM102
  • HIND 101和CHEM 102

然后,我会找到所有学生中最常见的组合。

2w3rbyxf

2w3rbyxf1#

我喜欢更形象的方法...

df <- scale(table(df[,2], df[,1]))
# calculate distance between Courses
d <- dist(df, method = "euclidean")
# Hierarchical clustering 
clustered <- hclust(d, method = "complete" )
# Plot dendrogram
plot(clustered)

字符串


的数据

# load sample data
df <- read.table(text = "Student    Course
001 PSYC101
001 CHEM102
002 PSYC101
002 SPAN101
002 BIO101
003 BIO101
003 ENG201
003 HIND101
003 CHEM102
004 PSYC101
004 CHEM102
004 HIND101", header = TRUE)

lsmepo6l

lsmepo6l2#

一个基本的R方法使用combn(选择2个元素)由学生创建每个特定学生的课程的所有组合,然后使用table来查看这些对在整个人群中出现的频率。
我将把合并后的代码放在下面,然后通过分解它来梳理出之后发生的事情,这样它就更可读/更容易理解了。
如果您想查看3个课程选项,请将combn(x$Course, 2)更改为combn(x$Course, 3)以选择三个课程的组合。

table(apply(do.call(cbind, lapply(split(df, df$Student), \(x)
                                  combn(x$Course, 2))), 2, \(x) paste(sort(x), collapse = "_")))

字符串
输出

# BIO101_CHEM102   BIO101_ENG201  BIO101_HIND101 CHEM102_HIND101  ENG201_CHEM102  ENG201_HIND101 
#               1               1               1               1               1               1 

# HIND101_CHEM102  PSYC101_BIO101 PSYC101_CHEM102 PSYC101_HIND101 PSYC101_SPAN101  SPAN101_BIO101 
#               1               1               2               1               1               1


首先,使用split将数据框(df)分解为每个学生的列表,然后找到课程的组合,然后组合并粘贴在一起,然后制作一个表格:

# Split by student
ll <- split(df, df$Student)

# find combinations of courses
combs_list <- lapply(ll, \(x) combn(unique(x$Course), 2))

# combine it into a matrix
combs_combined <- do.call(cbind, combs_list)

# paste combinations together
apply_combined <- apply(combs_combined, 2, \(x) paste(sort(x), collapse = "_"))

#make a table
table(apply_combined)


请注意,如果您希望将其放在数据框中,只需将表 Package 起来:

data.frame(tt)

# or to order by frequency:
data.frame(tt)[order(tt, decreasing = TRUE),]

#     apply_combined Freq
# 7  CHEM102_HIND101    2
# 8  CHEM102_PSYC101    2
# 1   BIO101_CHEM102    1
# 2    BIO101_ENG201    1
# 3   BIO101_HIND101    1
# ...


数据

df <- read.table(text = "Student    Course
001 PSYC101
001 CHEM102
002 PSYC101
002 SPAN101
002 BIO101
003 BIO101
003 ENG201
003 HIND101
003 CHEM102
004 PSYC101
004 CHEM102
004 HIND101", header = TRUE)

8tntrjer

8tntrjer3#

您可以筛选出行数少于感兴趣的m组合的学生,使用combn()生成组合,然后进行转置和行排序,解包tibble,计算结果,然后降序排序。

library(dplyr)
library(tidyr)

n <- 2

dat %>%
  filter(n() >= n, .by = Student) %>%
  reframe(x = t(combn(Course, n)) %>%
            {matrix(.[order(row(.), .)], ncol = ncol(.), byrow = TRUE)} %>%
            as_tibble(), .by = Student) |>
  unpack(x) |>
  count(across(-Student)) |>
  arrange(-n)

# A tibble: 11 × 3
   V1      V2          n
   <chr>   <chr>   <int>
 1 CHEM102 HIND101     2
 2 CHEM102 PSYC101     2
 3 BIO101  CHEM102     1
 4 BIO101  ENG201      1
 5 BIO101  HIND101     1
 6 BIO101  PSYC101     1
 7 BIO101  SPAN101     1
 8 CHEM102 ENG201      1
 9 ENG201  HIND101     1
10 HIND101 PSYC101     1
11 PSYC101 SPAN101     1

字符串
对于n = 3,您将获得:

# A tibble: 6 × 4
  V1      V2      V3          n
  <chr>   <chr>   <chr>   <int>
1 BIO101  CHEM102 ENG201      1
2 BIO101  CHEM102 HIND101     1
3 BIO101  ENG201  HIND101     1
4 BIO101  PSYC101 SPAN101     1
5 CHEM102 ENG201  HIND101     1
6 CHEM102 HIND101 PSYC101     1

n9vozmp4

n9vozmp44#

combn的另一种dplyr方法:

library(dplyr)
df |> 
  arrange(Student, Course) |> 
  reframe(Course_comb = combn(seq_along(Student), 2, function(i) paste(Course[i], collapse = " & ")), .by = Student) |> 
  count(Course_comb, sort = TRUE)

#          Course_comb n
# 1  CHEM102 & PSYC101 2
# 2  CHEM102 & HIND101 2
# 3   BIO101 & PSYC101 1
# 4   BIO101 & SPAN101 1
# 5  PSYC101 & SPAN101 1
# 6   BIO101 & CHEM102 1
# 7    BIO101 & ENG201 1
# 8   BIO101 & HIND101 1
# 9   CHEM102 & ENG201 1
# 10  ENG201 & HIND101 1
# 11 HIND101 & PSYC101 1

字符串

相关问题