使用循环和创建计数在知识测试中创建分数
Using loops and creating count to create score in a knowledge test
我有一个包含 11 个知识测试项目的数据集,目标是整理数据并在同一步骤中创建一个变量,代表参与者在 11 个项目中的每一个项目的项目分数。这些项目有不同数量的正确答案选项。在下面截取的代码中,只打印了此测试的前 2 个项目:factualPost_1_1_rw 代表项目 1 的第一个答案选项,factualPost_1_2_rw 代表项目 1 的第二个答案选项,依此类推。这些项目上的 0 和 1 并不表示参与者确实选择了正确答案。它们是先前编码的结果,如果选择的答案选项正确 (1) 或错误 (0),它们已经显示。
我的计划是使用以下公式计算 11 项中每一项的分数:
((一个项目中正确选择的答案选项的绝对数量 - 一个项目中错误选择的答案选项的绝对数量) / 项目中的答案选项总数)) * 可能的分数项目
“正确选择答案选项的绝对数”应为属于同一项目的“factualPost_x_x_rw”项上的“1”的总和,“绝对数选错选项”为某项答案选项中“0”的总和。与此相关的是,这两个绝对数的结果永远不会低于“0”。
“任务中的项目总数”的数量就是“正确选择答案选项的绝对数量”+“错误选择答案选项的绝对数量”之和;
11 个项目中的每个项目的“任务可能得分”设置为“2 分”。如果参与者在答案选项上显示 NA,则评估为错误选择的答案选项 (0)。
structure(list(id = c("AG07ER06", "AK08HN11", "AN04AD26", "AN04ND30",
"AN04RG15", "AN24ED27"), factualPost_1_1_rw = c(NA, NA, 0, 0,
1, NA), factualPost_1_2_rw = c(NA, NA, 1, 1, 1, NA), factualPost_1_3_rw = c(NA,
NA, 0, 0, 0, NA), factualPost_1_4_rw = c(NA, NA, 1, 0, 1, NA),
factualPost_1_5_rw = c(NA, NA, 0, 1, 1, NA), factualPost_2_1_rw = c(NA,
NA, 0, 0, 0, NA), factualPost_2_2_rw = c(NA, NA, 1, 0, 0,
NA), factualPost_2_3_rw = c(NA, NA, 1, 1, 1, NA), factualPost_2_4_rw = c(NA,
NA, 1, 0, 1, NA), factualPost_2_5_rw = c(NA, NA, 1, 0, 1,
NA), factualPost_2_6_rw = c(NA, NA, 1, 1, 1, NA)), row.names = c(NA,
-6L), class = c("tbl_df", "tbl", "data.frame"))
tbl_df [196 x 12] (S3: tbl_df/tbl/data.frame)
$ id : chr [1:196] "AG07ER06" "AK08HN11" "AN04AD26" "AN04ND30" ...
$ factualPost_1_1_rw: num [1:196] NA NA 0 0 1 NA NA 0 0 0 ...
$ factualPost_1_2_rw: num [1:196] NA NA 1 1 1 NA NA 0 1 1 ...
$ factualPost_1_3_rw: num [1:196] NA NA 0 0 0 NA NA 0 0 0 ...
$ factualPost_1_4_rw: num [1:196] NA NA 1 0 1 NA NA 1 1 0 ...
$ factualPost_1_5_rw: num [1:196] NA NA 0 1 1 NA NA 1 0 0 ...
$ factualPost_2_1_rw: num [1:196] NA NA 0 0 0 NA NA 1 0 0 ...
$ factualPost_2_2_rw: num [1:196] NA NA 1 0 0 NA NA 1 1 1 ...
$ factualPost_2_3_rw: num [1:196] NA NA 1 1 1 NA NA 1 1 1 ...
$ factualPost_2_4_rw: num [1:196] NA NA 1 0 1 NA NA 1 0 0 ...
$ factualPost_2_5_rw: num [1:196] NA NA 1 0 1 NA NA 1 0 0 ...
$ factualPost_2_6_rw: num [1:196] NA NA 1 1 1 NA NA 1 1 1 ...
***Edited***
Here comes how the table should look like in the end (presented just for the first item with its 5 answer options and for the first 5 participants):
id Item N Answered CorrectlyAnswered IncorrectlyAnswered Score
<chr> <chr> <int> <int> <dbl> <int> <dbl>
AG07ER06 factualPost_1_tot_rw 5 5 0 5 0
AK08HN11 factualPost_1_tot_rw 5 5 0 5 0
AN04AD26 factualPost_1_tot_rw 5 5 2 3 0 #(2-3=0; 0/5=0*2=0)
AN04ND30 factualPost_1_tot_rw 5 5 2 3 0
AN04RG15 factualPost_1_tot_rw 5 5 3 2 1.2 #(4-1=3; 3/5=0.6*2=1.2)
在我的评论中,我的意思与您似乎认为我的意思恰恰相反。您的数据不整齐因为您使用的是宽格式而不是长格式。您的数据在长格式中不整洁,因为列名称包含执行分析所需的信息:即您要汇总的项目。
你没有提供任何预期的输出,你的解释对我来说不是 100% 清楚,但我认为下面的代码接近你想要的。调用 pivot_longer()
整理您的数据,调用 group_by()
和 'summarise()` 计算您想要的统计数据。
library(tidyverse)
df %>%
pivot_longer(
-id,
names_to="Item",
values_to="Response"
) %>%
group_by(Item) %>%
summarise(
N=n(),
Answered=sum(!is.na(Response)),
CorrectlyAnswered=sum(Response, na.rm=TRUE),
IncorrectlyAnswered=sum(Response == 0, na.rm=TRUE),
Score=2*(CorrectlyAnswered - IncorrectlyAnswered)/N,
.groups="drop"
)
# A tibble: 11 x 6
Item N Answered CorrectlyAnswered IncorrectlyAnswered Score
<chr> <int> <int> <dbl> <int> <dbl>
1 factualPost_1_1_rw 6 3 1 2 -0.333
2 factualPost_1_2_rw 6 3 3 0 1
3 factualPost_1_3_rw 6 3 0 3 -1
4 factualPost_1_4_rw 6 3 2 1 0.333
5 factualPost_1_5_rw 6 3 2 1 0.333
6 factualPost_2_1_rw 6 3 0 3 -1
7 factualPost_2_2_rw 6 3 1 2 -0.333
8 factualPost_2_3_rw 6 3 3 0 1
9 factualPost_2_4_rw 6 3 2 1 0.333
10 factualPost_2_5_rw 6 3 2 1 0.333
11 factualPost_2_6_rw 6 3 3 0 1
我认为这种方法比处理宽格式数据更好的两个简单原因:代码 (a) 避免了任何循环需求,以及 (b) 对汇总的项目数量和标签都很稳健用于识别它们中的每一个。
我有一个包含 11 个知识测试项目的数据集,目标是整理数据并在同一步骤中创建一个变量,代表参与者在 11 个项目中的每一个项目的项目分数。这些项目有不同数量的正确答案选项。在下面截取的代码中,只打印了此测试的前 2 个项目:factualPost_1_1_rw 代表项目 1 的第一个答案选项,factualPost_1_2_rw 代表项目 1 的第二个答案选项,依此类推。这些项目上的 0 和 1 并不表示参与者确实选择了正确答案。它们是先前编码的结果,如果选择的答案选项正确 (1) 或错误 (0),它们已经显示。
我的计划是使用以下公式计算 11 项中每一项的分数:
((一个项目中正确选择的答案选项的绝对数量 - 一个项目中错误选择的答案选项的绝对数量) / 项目中的答案选项总数)) * 可能的分数项目
“正确选择答案选项的绝对数”应为属于同一项目的“factualPost_x_x_rw”项上的“1”的总和,“绝对数选错选项”为某项答案选项中“0”的总和。与此相关的是,这两个绝对数的结果永远不会低于“0”。 “任务中的项目总数”的数量就是“正确选择答案选项的绝对数量”+“错误选择答案选项的绝对数量”之和; 11 个项目中的每个项目的“任务可能得分”设置为“2 分”。如果参与者在答案选项上显示 NA,则评估为错误选择的答案选项 (0)。
structure(list(id = c("AG07ER06", "AK08HN11", "AN04AD26", "AN04ND30",
"AN04RG15", "AN24ED27"), factualPost_1_1_rw = c(NA, NA, 0, 0,
1, NA), factualPost_1_2_rw = c(NA, NA, 1, 1, 1, NA), factualPost_1_3_rw = c(NA,
NA, 0, 0, 0, NA), factualPost_1_4_rw = c(NA, NA, 1, 0, 1, NA),
factualPost_1_5_rw = c(NA, NA, 0, 1, 1, NA), factualPost_2_1_rw = c(NA,
NA, 0, 0, 0, NA), factualPost_2_2_rw = c(NA, NA, 1, 0, 0,
NA), factualPost_2_3_rw = c(NA, NA, 1, 1, 1, NA), factualPost_2_4_rw = c(NA,
NA, 1, 0, 1, NA), factualPost_2_5_rw = c(NA, NA, 1, 0, 1,
NA), factualPost_2_6_rw = c(NA, NA, 1, 1, 1, NA)), row.names = c(NA,
-6L), class = c("tbl_df", "tbl", "data.frame"))
tbl_df [196 x 12] (S3: tbl_df/tbl/data.frame)
$ id : chr [1:196] "AG07ER06" "AK08HN11" "AN04AD26" "AN04ND30" ...
$ factualPost_1_1_rw: num [1:196] NA NA 0 0 1 NA NA 0 0 0 ...
$ factualPost_1_2_rw: num [1:196] NA NA 1 1 1 NA NA 0 1 1 ...
$ factualPost_1_3_rw: num [1:196] NA NA 0 0 0 NA NA 0 0 0 ...
$ factualPost_1_4_rw: num [1:196] NA NA 1 0 1 NA NA 1 1 0 ...
$ factualPost_1_5_rw: num [1:196] NA NA 0 1 1 NA NA 1 0 0 ...
$ factualPost_2_1_rw: num [1:196] NA NA 0 0 0 NA NA 1 0 0 ...
$ factualPost_2_2_rw: num [1:196] NA NA 1 0 0 NA NA 1 1 1 ...
$ factualPost_2_3_rw: num [1:196] NA NA 1 1 1 NA NA 1 1 1 ...
$ factualPost_2_4_rw: num [1:196] NA NA 1 0 1 NA NA 1 0 0 ...
$ factualPost_2_5_rw: num [1:196] NA NA 1 0 1 NA NA 1 0 0 ...
$ factualPost_2_6_rw: num [1:196] NA NA 1 1 1 NA NA 1 1 1 ...
***Edited***
Here comes how the table should look like in the end (presented just for the first item with its 5 answer options and for the first 5 participants):
id Item N Answered CorrectlyAnswered IncorrectlyAnswered Score
<chr> <chr> <int> <int> <dbl> <int> <dbl>
AG07ER06 factualPost_1_tot_rw 5 5 0 5 0
AK08HN11 factualPost_1_tot_rw 5 5 0 5 0
AN04AD26 factualPost_1_tot_rw 5 5 2 3 0 #(2-3=0; 0/5=0*2=0)
AN04ND30 factualPost_1_tot_rw 5 5 2 3 0
AN04RG15 factualPost_1_tot_rw 5 5 3 2 1.2 #(4-1=3; 3/5=0.6*2=1.2)
在我的评论中,我的意思与您似乎认为我的意思恰恰相反。您的数据不整齐因为您使用的是宽格式而不是长格式。您的数据在长格式中不整洁,因为列名称包含执行分析所需的信息:即您要汇总的项目。
你没有提供任何预期的输出,你的解释对我来说不是 100% 清楚,但我认为下面的代码接近你想要的。调用 pivot_longer()
整理您的数据,调用 group_by()
和 'summarise()` 计算您想要的统计数据。
library(tidyverse)
df %>%
pivot_longer(
-id,
names_to="Item",
values_to="Response"
) %>%
group_by(Item) %>%
summarise(
N=n(),
Answered=sum(!is.na(Response)),
CorrectlyAnswered=sum(Response, na.rm=TRUE),
IncorrectlyAnswered=sum(Response == 0, na.rm=TRUE),
Score=2*(CorrectlyAnswered - IncorrectlyAnswered)/N,
.groups="drop"
)
# A tibble: 11 x 6
Item N Answered CorrectlyAnswered IncorrectlyAnswered Score
<chr> <int> <int> <dbl> <int> <dbl>
1 factualPost_1_1_rw 6 3 1 2 -0.333
2 factualPost_1_2_rw 6 3 3 0 1
3 factualPost_1_3_rw 6 3 0 3 -1
4 factualPost_1_4_rw 6 3 2 1 0.333
5 factualPost_1_5_rw 6 3 2 1 0.333
6 factualPost_2_1_rw 6 3 0 3 -1
7 factualPost_2_2_rw 6 3 1 2 -0.333
8 factualPost_2_3_rw 6 3 3 0 1
9 factualPost_2_4_rw 6 3 2 1 0.333
10 factualPost_2_5_rw 6 3 2 1 0.333
11 factualPost_2_6_rw 6 3 3 0 1
我认为这种方法比处理宽格式数据更好的两个简单原因:代码 (a) 避免了任何循环需求,以及 (b) 对汇总的项目数量和标签都很稳健用于识别它们中的每一个。