我如何从30个csv文件(每个文件有1个问题)中获取多项选择题的分数,并将它们组合成一组学生?(使用R)
学生们正在使用Zoom民意测验进行多项选择题(MCQ)测试班上有40名学生,有30个MCQ。我真的不知道投票是如何进行的,但课程教授告诉我Zoom将生成30个excel csv文件-每个MCQ一个。每个文件都有学生的姓名、ID以及MCQ答案的1分或0分 我的工作是找到一种方法来获取所有这30个csv文件(我保存在一个文件夹中),并合并它们以找到每个学生的总分。所以,我应该能够说出“凯特在30分中得了多少分?” 每个csv文件(将命名为MCQ1、MCQ2等)的外观如下:我如何从30个csv文件(每个文件有1个问题)中获取多项选择题的分数,并将它们组合成一组学生?(使用R),r,excel,csv,R,Excel,Csv,学生们正在使用Zoom民意测验进行多项选择题(MCQ)测试班上有40名学生,有30个MCQ。我真的不知道投票是如何进行的,但课程教授告诉我Zoom将生成30个excel csv文件-每个MCQ一个。每个文件都有学生的姓名、ID以及MCQ答案的1分或0分 我的工作是找到一种方法来获取所有这30个csv文件(我保存在一个文件夹中),并合并它们以找到每个学生的总分。所以,我应该能够说出“凯特在30分中得了多少分?” 每个csv文件(将命名为MCQ1、MCQ2等)的外观如下: Name SID
Name SID Score
Kate 534 1
Bret 411 0
Jade 325 1
Name SID MCQ1 MCQ2 MCQ3 MCQ4 MCQ5 ... Total
Kate 534 1 1 0 1 0 ... (=sum)
Bret 411 0 0 0 1 1 ... (=sum)
Jade 325 1 0 1 1 0 ... (=sum)
我必须使用R来完成此操作。这就是我需要的:
Name SID Score
Kate 534 1
Bret 411 0
Jade 325 1
Name SID MCQ1 MCQ2 MCQ3 MCQ4 MCQ5 ... Total
Kate 534 1 1 0 1 0 ... (=sum)
Bret 411 0 0 0 1 1 ... (=sum)
Jade 325 1 0 1 1 0 ... (=sum)
需要做的是R需要使用“Name”或“SID”查找每个学生的MCQ分数,并且只将分数一个接一个地堆叠起来
我已经在SO中查看了以下帖子
以下是我到目前为止的情况:
total_score <- list.files(pattern = "*.csv") %>% map_df(read_csv)
Name SID Score
Kate 534 1
Bret 411 0
Jade 325 1
Kate 534 1
Bret 411 0
Jade 325 0
Kate 534 0
Bret 411 0
Jade 325 1
Kate 534 1
Bret 411 1
Jade 325 1
Kate 534 0
Bret 411 1
Jade 325 0
总分%map\u df(读取\u csv)
名称SID分数
凯特5341
布雷特4110
翡翠325 1
凯特5341
布雷特4110
翡翠3250
凯特5340
布雷特4110
翡翠325 1
凯特5341
布雷特4111
翡翠325 1
凯特5340
布雷特4111
翡翠3250
我如何告诉R不要重复前两列,只从每个特定学生的文件中获取每个“分数”列,然后将它们作为以csv文件命名的新列?有人能给我指出正确的方向吗?我们可以通过使用
basename
提取文件名,然后循环“文件”,使用read\u csv
读取数据,使用文件名('nm1')重命名“Score”,从而将“Score”列重命名为文件名,通过
“名称”、“SID”连接数据集,将其缩减为单个数据集,然后通过执行以“MCQ”开头的列的行和
,创建“总计”列
library(readr)
library(dplyr)
library(purrr)
files <- list.files(pattern = "*.csv")
nm1 <- tools::file_path_sans_ext(basename(files))
imap(setNames(files, nm1),
~ {
nm <- .y
read_csv(.x) %>%
rename_at(vars(Score), ~ nm)
}) %>%
reduce(full_join, by = c('Name', 'SID')) %>%
mutate(Total = rowSums(select(., starts_with('MCQ'))))
尝试此base R
选项,使用内置函数加载和格式化名称。该函数的主要思想是根据文件列表加载文件,然后将文件名分配给score变量。之后,使用lappy()
、Reduce()
和merge()
压缩数据,以便使用rowSums()
获得总变量(我们排除前两个变量,因为它们是学生的姓名和人数)。我已经根据您共享的输出使用一些虚拟文件进行了测试。代码如下:
#Obtain files
v1 <- list.files(pattern = '*.csv')
#Function for load
myload <- function(x)
{
#Name for var
vname <- gsub('.csv','',x)
#Load data
y <- read.csv(x,stringsAsFactors = F)
#Rename the score var
names(y)[3] <- vname
#Return
return(y)
}
#Apply
List <- lapply(v1,myload)
#Now merge
df <- Reduce(function(x, y) merge(x, y, by=c('Name','SID'),all=TRUE), List)
#Compute total
df$Total <- rowSums(df[,-c(1,2)],na.rm=T)
你好,鸭子,谢谢你的回答。步骤“#Now merge”中的代码给出了一个错误:fix.by(by.x,x)中的错误:“by”必须指定唯一有效的列。有什么想法吗?@AIQ可能您的一个csv文件没有所需的变量!我选中了,我的csv文件都有3列6行(包括标题),它们都匹配。@AIQ我认为唯一的一点是某些名称可能不同,这会产生错误。@AIQ还尝试在read.csv()中添加stringsAsFactors=F
)
位于阅读功能内部,或者使用lappy(List,names)
Woooh探索列表中的所有名称是否相等。谢谢阿克伦!不过我有一个问题。假设每个csv文件中的学生姓名顺序不同(例如,MCQ1中的Bret位于第一行,MCQ2中的Bret位于第17行)。你的代码仍然有效吗?还是需要一些更改?@AIQ顺序无关紧要,因为我们正在进行一个连接,该连接与所有数据集中的“Name”和“SID”匹配
Name SID MCQ1 MCQ2 MCQ3 MCQ4 MCQ5 Total
1 Bret 411 0 0 0 1 1 2
2 Jade 325 1 0 1 1 0 3
3 Kate 534 1 1 0 1 0 3