如果我有这样的数据框,可以将其视为不同受访者的调查回复
Data =
ID Q1 Q2 Q3
1 A1 B2 C3
2 A2 B1 C2
3 A1 B2 C3
...
我还有以下分数表:
Q1 <- (c("A1", 10, "A2", 20, ...))
Q2 <- (c("B1", 10, "B2", 20, ...))
Q3 <- (c("C1", 10, "C2", 20, ...))
这意味着,如果我在Q1中选择“A1”,我得到10分,如果我在Q2中选择“B2”,我会得到20分,如果我在Q3中选择“C1”,那么也是10分标记,我得到的总分是: 10(A1)+20(B2)+ 10(C1)= 40
现在,对于数据中的每一行,我需要根据得分表对每列的得分进行求和来计算总得分。
任何人都可以建议我如何使用简单的代码吗? 现在我只能考虑将得分表放到Xx2矩阵中,并使用大量的嵌套if和for循环。
答案 0 :(得分:1)
数据:
Data <- read.table(text = "ID Q1 Q2 Q3
1 A1 B2 C3
2 A2 B1 C2
3 A1 B2 C3", header = TRUE)
Q1 <- c("A1", 10, "A2", 20)
Q2 <- c("B1", 10, "B2", 20)
Q3 <- c("C1", 10, "C2", 20)
首先,创建Q
个对象的列表:
Qlist <- list(Q1 = Q1, Q2 = Q2, Q3 = Q3)
现在,可以使用sapply
:
cbind(Data,
QSum = rowSums(sapply(names(Qlist),
function(q)
as.numeric(Qlist[[q]][match(Data[[q]],
Qlist[[q]]) + 1])),
na.rm = TRUE))
输出:
ID Q1 Q2 Q3 QSum
1 1 A1 B2 C3 30
2 2 A2 B1 C2 50
3 3 A1 B2 C3 30
答案 1 :(得分:1)
df <- read.table(text="ID Q1 Q2 Q3
1 A1 B2 C3
2 A2 B1 C2
3 A1 B2 C3",header=TRUE, stringsAsFactors=FALSE)
scores <- list(
Q1 = c("A1", 10, "A2", 20, "A3", 30),
Q2 =c("B1", 30, "B2", 10, "B3", 20),
Q3 =c("C1", 10, "C2", 30, "C3", 20)
)
#lookup table
scores <- do.call("cbind",scores)
#match
m <- apply(df[,-1],2,match,table=scores)
#look up
points <- matrix(as.numeric(scores[m+1]),ncol=ncol(df)-1)
#sum for each ID
result <- cbind(df,Score=rowSums(points))
ID Q1 Q2 Q3 Score
1 1 A1 B2 C3 40
2 2 A2 B1 C2 80
3 3 A1 B2 C3 40
答案 2 :(得分:1)
我将使用罗兰所选择的“得分”。既然你提到你可以将得分表改为2x2矩阵,我提供下面的解决方案,与其他2有不同的分数数据结构。
在我提供代码之前,请允许我解释逻辑:
基于2,我觉得需要一个关联数组,我可以根据问题编号和索引进行索引。输入答案。因此,我为分数创建了以下表示:
> scores <- list(
+ Q1 = list(A1=10,A2=20,A3=30),
+ Q2 = list(B1=30,B2=10,B3=20),
+ Q3 = list(C1=10,C2=30,C3=20)
+ )
基本上,分数现在是列表列表。通过这样做,我可以做到以下几点:
> scores[["Q1"]][["A1"]]
[1] 10
现在我需要做的就是找出一种方法来参数化“Q1”&amp;上面的“A1”。
数据框“df”如下:
> df
ID Q1 Q2 Q3
1 1 A1 B2 C3
2 2 A2 B1 C2
3 3 A1 B2 C3
我关心的是,每一行都没有ID列。所以,我只提取:
> df[1,-1]
Q1 Q2 Q3
1 A1 B2 C3
到目前为止,你可以看到我需要为第一个索引选择分数和分数。第二个索引的行中的值。因此,如果我能得到分数[[column-M]] [[row-NvalueForColumn-M]],那么我可以总结一下。
因此很容易获得列名称:
> columnNames <- colnames(df[1,-1])
> columnNames
[1] "Q1" "Q2" "Q3"
所以你做出必要逻辑的最后一段代码是:
> columnNames <- colnames(df[1,-1])
> score <- c(0,0,0)
> for (i in 1:length(df[1,-1]))
+ {
+ for (j in 1:length(columnNames))
+ {
+ score[i] <- score[i] + scores[[columnNames[j]]][[df[i,-1][[columnNames[j]]]]]
+ }
+ }
> final <- cbind(df,score)
> final
ID Q1 Q2 Q3 score
1 1 A1 B2 C3 40
2 2 A2 B1 C2 80
3 3 A1 B2 C3 40
>
我相信上面的代码可以减少至少5行(使用rowums等)。我相信像Sven这样经验丰富的人可以将上面的代码改进为几行。希望得到投入。