使用 R 从每个用户多次提交的调查数据中确定累积分数
Determining Cumulative Score from Survey Data with Multiple Submissions per User Using R
我创建了一个调查表,并在 R 中收集了结果。调查中有很多问题,它们被分成几个部分。例如,前三个问题属于以下类别:行为。用户可以在初次提交后返回调查以更新他们的答案(所有问题均为 True/False)。考虑到用户可以返回并更新他们的答案,我正在努力随着时间的推移开发一个累积分数。以下是行为类别的调查数据结果示例:
调查数据:
我想开发一个分数,它将采用用户最近的调查结果,但我需要保留以前的提交数据以显示进度。例如,这是我想要的结果:
结果:
Score 列的公式为(#Trues for that day/(number_of_submissions for that day/number of questions for that category)。行为类别的问题数量为 3 . 然而,当用户重新提交带有新答案的调查时,我正在努力计算分数。知道我如何在 R 中做到这一点吗?
这是我目前的方法,计算累积分数,但不考虑用户是否多次提交调查,因为它不会覆盖并采用最近的调查结果。
可重现的例子:
user <- c('User1', 'User1', 'User1', 'User2', 'User3', 'User3')
submission_date <- as.Date(c('2016-09-04', '2016-09-15', '2016-09-29', '2016-09-04', '2016-09-05', '2016-09-20'))
Trues_Behavior_Category <- c(1,2,3,3,2,3)
survey_data <- data.frame(user, submission_date, Trues_Behavior_Category)
checklist_data_weekly <- aggregate(survey_data[c(3)], list(Sub_Date = as.Date(survey_data$submission_date)), sum)
checklist_data_cum <- cbind(checklist_data_weekly[c(1)], cumsum(checklist_data_weekly[c(2)]))
sub_count <- aggregate(survey_data[c(1)], list(Sub_Date = as.Date(survey_data$submission_date)), length)
sub_count <- cbind(sub_count[c(1)], Cum_Dates=cumsum(sub_count$user))
checklist_data_cum$Behaviors_Score <- (checklist_data_cum$Trues_Behavior_Category/(sub_count$Cum_Dates*3)*100)
一种方法是创建一个函数来获取日期 x 的用户数量,一个获取每个用户在日期 的最新响应的函数x,然后是将这些函数应用于数据中的用户和日期的函数:
user <- c('User1', 'User1', 'User1', 'User2', 'User3', 'User3')
submission_date <- as.Date(c('2016-09-04', '2016-09-15', '2016-09-29',
'2016-09-04', '2016-09-05', '2016-09-20'))
Trues_Behavior_Category <- c(1, 2, 3, 3, 2, 3)
survey_data <- data.frame(user, submission_date, Trues_Behavior_Category,
stringsAsFactors=FALSE)
get_last_submission <- function(user, df, date, col_name){
df <- df[df$user == user & df$submission_date <= date, ]
return(df[order(df$submission_date, decreasing=TRUE)[1], col_name])
}
get_current_user_n <- function(df, date){
return(length(unique(df$user[df$submission_date <= date])))
}
get_score <- function(df, col_name, num_questions){
users <- unique(df$user)
return(sapply(sort(unique(df$submission_date)), function(x){
(sum(as.numeric(sapply(users, get_last_submission, df, x, col_name)),
na.rm=TRUE) / (get_current_user_n(df, x) * num_questions))
}))
}
behavior_scores <- get_score(survey_data, 'Trues_Behavior_Category', 3)
behavior_scores
[1] 0.6666667 0.6666667 0.7777778 0.8888889 1.0000000
final_result <- data.frame(Sub_Date=sort(unique(survey_data$submission_date)),
Behaviors_Score=behavior_scores)
final_result
Sub_Date Behaviors_Score
1 2016-09-04 0.6666667
2 2016-09-05 0.6666667
3 2016-09-15 0.7777778
4 2016-09-20 0.8888889
5 2016-09-29 1.0000000
如您所见,结果是要求的 2/3、2/3、7/9、8/9 和 1。
编辑:
我意识到我没有解释函数的参数; df
是包含您的调查数据的数据框,col_name
是您要为其评分的列的名称,num_questions
是该类别的问题数。
我创建了一个调查表,并在 R 中收集了结果。调查中有很多问题,它们被分成几个部分。例如,前三个问题属于以下类别:行为。用户可以在初次提交后返回调查以更新他们的答案(所有问题均为 True/False)。考虑到用户可以返回并更新他们的答案,我正在努力随着时间的推移开发一个累积分数。以下是行为类别的调查数据结果示例:
调查数据:
我想开发一个分数,它将采用用户最近的调查结果,但我需要保留以前的提交数据以显示进度。例如,这是我想要的结果:
结果:
Score 列的公式为(#Trues for that day/(number_of_submissions for that day/number of questions for that category)。行为类别的问题数量为 3 . 然而,当用户重新提交带有新答案的调查时,我正在努力计算分数。知道我如何在 R 中做到这一点吗?
这是我目前的方法,计算累积分数,但不考虑用户是否多次提交调查,因为它不会覆盖并采用最近的调查结果。
可重现的例子:
user <- c('User1', 'User1', 'User1', 'User2', 'User3', 'User3')
submission_date <- as.Date(c('2016-09-04', '2016-09-15', '2016-09-29', '2016-09-04', '2016-09-05', '2016-09-20'))
Trues_Behavior_Category <- c(1,2,3,3,2,3)
survey_data <- data.frame(user, submission_date, Trues_Behavior_Category)
checklist_data_weekly <- aggregate(survey_data[c(3)], list(Sub_Date = as.Date(survey_data$submission_date)), sum)
checklist_data_cum <- cbind(checklist_data_weekly[c(1)], cumsum(checklist_data_weekly[c(2)]))
sub_count <- aggregate(survey_data[c(1)], list(Sub_Date = as.Date(survey_data$submission_date)), length)
sub_count <- cbind(sub_count[c(1)], Cum_Dates=cumsum(sub_count$user))
checklist_data_cum$Behaviors_Score <- (checklist_data_cum$Trues_Behavior_Category/(sub_count$Cum_Dates*3)*100)
一种方法是创建一个函数来获取日期 x 的用户数量,一个获取每个用户在日期 的最新响应的函数x,然后是将这些函数应用于数据中的用户和日期的函数:
user <- c('User1', 'User1', 'User1', 'User2', 'User3', 'User3')
submission_date <- as.Date(c('2016-09-04', '2016-09-15', '2016-09-29',
'2016-09-04', '2016-09-05', '2016-09-20'))
Trues_Behavior_Category <- c(1, 2, 3, 3, 2, 3)
survey_data <- data.frame(user, submission_date, Trues_Behavior_Category,
stringsAsFactors=FALSE)
get_last_submission <- function(user, df, date, col_name){
df <- df[df$user == user & df$submission_date <= date, ]
return(df[order(df$submission_date, decreasing=TRUE)[1], col_name])
}
get_current_user_n <- function(df, date){
return(length(unique(df$user[df$submission_date <= date])))
}
get_score <- function(df, col_name, num_questions){
users <- unique(df$user)
return(sapply(sort(unique(df$submission_date)), function(x){
(sum(as.numeric(sapply(users, get_last_submission, df, x, col_name)),
na.rm=TRUE) / (get_current_user_n(df, x) * num_questions))
}))
}
behavior_scores <- get_score(survey_data, 'Trues_Behavior_Category', 3)
behavior_scores
[1] 0.6666667 0.6666667 0.7777778 0.8888889 1.0000000
final_result <- data.frame(Sub_Date=sort(unique(survey_data$submission_date)),
Behaviors_Score=behavior_scores)
final_result
Sub_Date Behaviors_Score
1 2016-09-04 0.6666667
2 2016-09-05 0.6666667
3 2016-09-15 0.7777778
4 2016-09-20 0.8888889
5 2016-09-29 1.0000000
如您所见,结果是要求的 2/3、2/3、7/9、8/9 和 1。
编辑:
我意识到我没有解释函数的参数; df
是包含您的调查数据的数据框,col_name
是您要为其评分的列的名称,num_questions
是该类别的问题数。