使用 R 中的 for 循环确定来自 Qualtrics 的随机集中项目的顺序
Determining order of item in randomized set from Qualtrics using a for loop in R
在我的一项 Qualtrics 调查中,每位参与者都会收到一组随机排列的问题。
我现在想确定一个问题(参见 table 中的 "Question" 变量)在参与者的随机问题顺序中的位置。缩短示例中的问题编号为 I1、I2 或 I3。
现在对数据进行组织,以便有与顺序相对应的列(在下面的简短示例中,"B1"、"B2" 和 "B3")。也就是说,B1 列中的问题首先出现在该参与者身上。
这是一个数据文件 (https://drive.google.com/open?id=1h18SlQ-gmRUZh93M5Y5T3TuE22yxSJbU),这是在 R 中打印出来的样子:
> head(testd)
Question B1 B2 B3
1 I1 I1 I2 I3
2 I1 I3 I2 I1
3 I2 I2 I3 I1
4 I2 I3 I1 I2
5 I3 I2 I1 I3
6 I3 I1 I3 I2
我现在想写一个 for 循环来在数据框 testd 中创建一个新变量 "RandomizedOrder",它会告诉我 "Question" 列(例如 I1)中的问题是否针对参与者第一个 (B1)、第二个 (B2) 或第三个 (B3)。例如,在上面的示例中,第 1 行的 RandomizedOrder 应该是 B1,因为列 "Question" 中的值是 I1,而列 "B1" 中的值是 I1。
为此,我首先将值 "B1"、"B2" 和 "B3" 连接在 "BSet" 中。
testd <- read.csv("TestData.csv")
BSet <- c("B1", "B2", "B3")
testd[BSet]
然后我写了下面的for循环。我的目标:对于每一行 i,如果三个 BSet 列之一中的某个值与问题列中的值相同,则该行的变量 RandomizedOrder 应采用其中一个值的列名B设置与问题列中的值相同的列。
例如,如果第 1 行中的 testd$B1 = I1,并且第 1 行中的 testd$Question = I1,则此 for 循环应使 testd$RandomizedOrder 等于 B1。
for (i in nrow(testd)) {
for (j in 1:3) {
if (testd[i,BSet][[j]] == testd$Question[i]) {
testd$RandomizedOrder[i] <- colnames(testd[i,BSet][j])
}
}
}
这就是 R 输出的样子。
> head(testd$RandomizedOrder)
[1] NA NA NA NA NA "B2"
我不确定为什么它会为除第 6 项以外的所有内容生成 NA 值。
这是我希望 for 循环执行的操作:创建一个名为 "RandomizedOrder" 的新变量,该变量指示每一行的哪一列包含在 "Question" 列中找到的值。
Question B1 B2 B3 RandomizedOrder
1 I1 I1 I2 I3 B1
2 I1 I3 I2 I1 B3
3 I2 I2 I3 I1 B2
4 I2 I3 I1 I2 B3
5 I3 I2 I1 I3 B3
6 I3 I1 I3 I2 B2
我查看了代码以确保各个部分都能正常工作。
这里的代码结果为真(等号两边都产生值 I1):
testd[1,BSet][[1]] == testd$Question[1]
[1] TRUE
我也可以手动告诉 R 用列名替换 testd$RandomizedOrder 中的值。
> testd$RandomizedOrder[1] <- colnames(testd[1,BSet][1])
> head(testd$RandomizedOrder)
[1] "B1" NA NA NA NA "B2"
有人可以帮我确定为什么 for 循环不起作用吗?
提前致谢。
(请注意,对于具有 6 个观察值的数据集,这似乎可以很容易地手动完成,但这是我的真实数据集的简化示例。我的实际数据集有 48 个问题(即 I1 到 I48) , 以及数百个观察结果。因此,我使用字母 j 对 BSet 表示的列数进行了索引。)
考虑 lapply
跨数据框列名称进行匹配,然后是 Reduce
进行 coalesce method 以将所有列减少为一个 RandomizedOrder作业。
txt = "Question B1 B2 B3
1 I1 I1 I2 I3
2 I1 I3 I2 I1
3 I2 I2 I3 I1
4 I2 I3 I1 I2
5 I3 I2 I1 I3
6 I3 I1 I3 I2"
testd <- read.table(text=txt, header=TRUE)
colList <- lapply(names(testd)[-1], function(i)
ifelse(testd$Question == testd[[i]], i, NA))
testd$RandomizedOrder <- Reduce(function(x, y) {
x[which(is.na(x))] <- y[which(is.na(x))]
x}, colList)
testd
# Question B1 B2 B3 RandomizedOrder
# 1 I1 I1 I2 I3 B1
# 2 I1 I3 I2 I1 B3
# 3 I2 I2 I3 I1 B1
# 4 I2 I3 I1 I2 B3
# 5 I3 I2 I1 I3 B3
# 6 I3 I1 I3 I2 B2
在我的一项 Qualtrics 调查中,每位参与者都会收到一组随机排列的问题。
我现在想确定一个问题(参见 table 中的 "Question" 变量)在参与者的随机问题顺序中的位置。缩短示例中的问题编号为 I1、I2 或 I3。
现在对数据进行组织,以便有与顺序相对应的列(在下面的简短示例中,"B1"、"B2" 和 "B3")。也就是说,B1 列中的问题首先出现在该参与者身上。
这是一个数据文件 (https://drive.google.com/open?id=1h18SlQ-gmRUZh93M5Y5T3TuE22yxSJbU),这是在 R 中打印出来的样子:
> head(testd)
Question B1 B2 B3
1 I1 I1 I2 I3
2 I1 I3 I2 I1
3 I2 I2 I3 I1
4 I2 I3 I1 I2
5 I3 I2 I1 I3
6 I3 I1 I3 I2
我现在想写一个 for 循环来在数据框 testd 中创建一个新变量 "RandomizedOrder",它会告诉我 "Question" 列(例如 I1)中的问题是否针对参与者第一个 (B1)、第二个 (B2) 或第三个 (B3)。例如,在上面的示例中,第 1 行的 RandomizedOrder 应该是 B1,因为列 "Question" 中的值是 I1,而列 "B1" 中的值是 I1。
为此,我首先将值 "B1"、"B2" 和 "B3" 连接在 "BSet" 中。
testd <- read.csv("TestData.csv")
BSet <- c("B1", "B2", "B3")
testd[BSet]
然后我写了下面的for循环。我的目标:对于每一行 i,如果三个 BSet 列之一中的某个值与问题列中的值相同,则该行的变量 RandomizedOrder 应采用其中一个值的列名B设置与问题列中的值相同的列。
例如,如果第 1 行中的 testd$B1 = I1,并且第 1 行中的 testd$Question = I1,则此 for 循环应使 testd$RandomizedOrder 等于 B1。
for (i in nrow(testd)) {
for (j in 1:3) {
if (testd[i,BSet][[j]] == testd$Question[i]) {
testd$RandomizedOrder[i] <- colnames(testd[i,BSet][j])
}
}
}
这就是 R 输出的样子。
> head(testd$RandomizedOrder)
[1] NA NA NA NA NA "B2"
我不确定为什么它会为除第 6 项以外的所有内容生成 NA 值。
这是我希望 for 循环执行的操作:创建一个名为 "RandomizedOrder" 的新变量,该变量指示每一行的哪一列包含在 "Question" 列中找到的值。
Question B1 B2 B3 RandomizedOrder
1 I1 I1 I2 I3 B1
2 I1 I3 I2 I1 B3
3 I2 I2 I3 I1 B2
4 I2 I3 I1 I2 B3
5 I3 I2 I1 I3 B3
6 I3 I1 I3 I2 B2
我查看了代码以确保各个部分都能正常工作。
这里的代码结果为真(等号两边都产生值 I1):
testd[1,BSet][[1]] == testd$Question[1] [1] TRUE
我也可以手动告诉 R 用列名替换 testd$RandomizedOrder 中的值。
> testd$RandomizedOrder[1] <- colnames(testd[1,BSet][1])
> head(testd$RandomizedOrder)
[1] "B1" NA NA NA NA "B2"
有人可以帮我确定为什么 for 循环不起作用吗?
提前致谢。
(请注意,对于具有 6 个观察值的数据集,这似乎可以很容易地手动完成,但这是我的真实数据集的简化示例。我的实际数据集有 48 个问题(即 I1 到 I48) , 以及数百个观察结果。因此,我使用字母 j 对 BSet 表示的列数进行了索引。)
考虑 lapply
跨数据框列名称进行匹配,然后是 Reduce
进行 coalesce method 以将所有列减少为一个 RandomizedOrder作业。
txt = "Question B1 B2 B3
1 I1 I1 I2 I3
2 I1 I3 I2 I1
3 I2 I2 I3 I1
4 I2 I3 I1 I2
5 I3 I2 I1 I3
6 I3 I1 I3 I2"
testd <- read.table(text=txt, header=TRUE)
colList <- lapply(names(testd)[-1], function(i)
ifelse(testd$Question == testd[[i]], i, NA))
testd$RandomizedOrder <- Reduce(function(x, y) {
x[which(is.na(x))] <- y[which(is.na(x))]
x}, colList)
testd
# Question B1 B2 B3 RandomizedOrder
# 1 I1 I1 I2 I3 B1
# 2 I1 I3 I2 I1 B3
# 3 I2 I2 I3 I1 B1
# 4 I2 I3 I1 I2 B3
# 5 I3 I2 I1 I3 B3
# 6 I3 I1 I3 I2 B2