成对比较的二进制编码

时间:2016-02-01 09:56:25

标签: r matrix

我正在制作一份调查问卷,其中一次总共有三种陈述,参与者必须根据他们的偏好对这些陈述进行排序(3 =最优先,1 =最不喜欢)。

对于进一步的分析,我必须将这些排名转换为每个三个块内的成对比较。下面是调查问卷前六项(2个街区)的代码。

data <- matrix(c(1,2,3,1,2,3,2,1,3,3,1,2),2,6)

i1i2 <- ifelse(data[,1] > data[,2], 1, 0)
i1i3 <- ifelse(data[,1] > data[,3], 1, 0)
i2i3 <- ifelse(data[,2] > data[,3], 1, 0) 

i4i5 <- ifelse(data[,4] > data[,5], 1, 0)
i4i6 <- ifelse(data[,4] > data[,6], 1, 0)
i5i6 <- ifelse(data[,5] > data[,6], 1, 0)

result <- cbind(i1i2, i1i3, i2i3, i4i5, i4i6, i5i6)
print(result)

我将此代码扩展为适合45项问卷,并且工作正常。现在,我想编写一个自动为n项工作的函数。我尝试了while和for循环,但无法成功。

任何人都可以给我一个提示/参考我需要的相关功能/如何做到这一点的例子?

相关:Brown,A。,&amp; Maydeu-Olivares,A。(2011年)。强制选择问卷的项目反应建模。教育和心理测量,71(3),460-502。

2 个答案:

答案 0 :(得分:2)

虽然可能有更高效的替代方案,但您可以将矩阵转换为长度为3的向量列表,并通过函数将ifelse语句应用于它们。

<强>更新

如果矩阵中有多行,则需要使用t(data)内的split()来获取正确的值。

# Put data in lists of 3
blocks <- split(t(data), ceiling(seq_along(data)/3))

# Define function
comparison <-function(x) {

i1 <- ifelse(x[1] > x[2], 1, 0)
i2 <- ifelse(x[1] > x[3], 1, 0)
i3 <- ifelse(x[2] > x[3], 1, 0) 

return(cbind(i1,i2,i3))

}

# Apply function to list
lapply(blocks,comparison)
# $`1`
#     i1 i2 i3
# [1,]  0  0  1
#
# $`2`
#     i1 i2 i3
# [1,]  0  1  1
#
# $`3`
#      i1 i2 i3
# [1,]  1  0  0
#
# $`4`
#     i1 i2 i3
# [1,]  0  0  1


# Or unlist to get vector
unlist(lapply(blocks,comparison))
# 11 12 13 21 22 23 31 32 33 41 42 43 
#  0  0  1  0  1  1  1  0  0  0  0  1 

答案 1 :(得分:2)

首先,删除ifelse并将其放在最后:

i1i2 <- data[,1] > data[,2]
i1i3 <- data[,1] > data[,3]
i2i3 <- data[,2] > data[,3]
…
result <- ifelse(cbind(i1i2, i1i3, i2i3, i4i5, i4i6, i5i6), 1, 0)

接下来,避免不必要的重复。

three_way_compare = function (data, index) {
    cbind(data[, index + 0] > data[, index + 1],
          data[, index + 0] > data[, index + 2],
          data[, index + 1] > data[, index + 2])
}

result = ifelse(do.call(cbind, lapply(seq(1, ncol(data), by = 3),
                                      three_way_compare, data = data)), 1, 0)