用粘贴在R中写一个循环?

时间:2013-11-21 19:26:00

标签: r

我正在尝试使用for循环编写这段代码。

#Took Quiz X and 1
TookQuizX[1,1] <- nrow(Q1[Q1$anon_user_id %in% Q1$anon_user_id,])
TookQuizX[2,1] <- nrow(Q2[Q2$anon_user_id %in% Q1$anon_user_id,])
TookQuizX[3,1] <- nrow(Q3[Q3$anon_user_id %in% Q1$anon_user_id,])
TookQuizX[4,1] <- nrow(Q4[Q4$anon_user_id %in% Q1$anon_user_id,])
TookQuizX[5,1] <- nrow(Q5[Q5$anon_user_id %in% Q1$anon_user_id,])
TookQuizX[6,1] <- nrow(Q6[Q6$anon_user_id %in% Q1$anon_user_id,])

我尝试的是以下

for(i in 1:6){
  Qx<-paste("Q",i,"[Q",i,"$anon_user_id",sep="")
  TookQuizX[i,1] <- nrow(Qx %in% Q1$anon_user_id,])
}

当我运行循环时,我收到以下错误:

Error: unexpected ']' in:
"  Qx<-paste("Q",i,"[Q",i,"$anon_user_id",sep="")
  TookQuizX[i,1] <- nrow(Qx %in% Q1$anon_user_id,]"
> }
Error: unexpected '}' in "}

我做错了什么?

谢谢!


这个非常简单的例子有希望说明我正在尝试做什么

TookQuizX <- matrix(data=NA,nrow=3,ncol=1)
Q1 <- data.frame(anon_user_id = c("A123", "A111", "A134", "A156"), other_stuf=999)
Q2 <- data.frame(anon_user_id = c("A123", "A234", "A111", "A256", "C521"), other_stuf=999)
Q3 <- data.frame(anon_user_id = c("A123", "A234", "A111", "A356", "B356"), other_stuf=999)

TookQuizX[1,1] <- nrow(Q1[Q1$anon_user_id %in% Q1$anon_user_id,])
TookQuizX[2,1] <- nrow(Q2[Q2$anon_user_id %in% Q1$anon_user_id,])
TookQuizX[3,1] <- nrow(Q3[Q3$anon_user_id %in% Q1$anon_user_id,])

3 个答案:

答案 0 :(得分:3)

与R中的许多操作一样,将数据框包装在列表中更容易。

Q_all <- list(Q1,Q2,Q3)

首先,为什么不直接衡量nrow向量中有多少TRUE个值,而不是使用%in%

TookQuizX[1,1] <- length(which(Q1$anon_user_id %in% Q1$anon_user_id))

要替换循环,以下是lapply的示例:

TookQuizX[,1] <- unlist(lapply(Q_all, function(x) length(which(x$anon_user_id %in% Q_all[[1]]$anon_user_id))))

我认为最后,您希望TookQuizX成为一个矩阵,其中条目i,j是参加测验的人数i,并且还参加了测验j 。另外,我假设您的用户ID是唯一的,并且数据框中没有两行具有相同的用户ID。然后让我们从数据框中提取用户ID。

anon_user_ids <- lapply(Q_all, `[[`, "anon_user_id")

将这些放在一起的一种方式(并且有更有效的方法,但首先想到的是)Map

tmp <- Map(function(x,y) length(which(x %in% y)),
  anon_user_ids[rep(seq_along(anon_user_ids),times = length(anon_user_ids))] ,
  anon_user_ids[rep(seq_along(anon_user_ids),each = length(anon_user_ids))] )

这会迭代地比较ij的交集,因此1,12,13,11,2,{{1}等等。现在我可以将它放入矩阵中。默认情况下,在R中的矩阵和数组中,假设向量按列主要顺序排列(第一个维度变化最快,最后一个维度变化最慢)。

2,2

答案 1 :(得分:1)

你需要做两件事。首先,您需要重新创建要运行的命令:

for(i in 1:6){
  Qx <- paste("TookQuizX[1,", i, "] <- nrow(Q", i, "[Q", i,
              "$anon_user_id %in% Q1$anon_user_id,])", sep = "")
  print(Qx)
}

此循环将生成您要评估为代码的字符串。为此,您需要告诉R将字符串解释为实际代码。这涉及将文本解析为代码,然后评估代码。修改我们得到的第一个循环:

for(i in 1:6){
  Qx <- paste("TookQuizX[1,", i, "] <- nrow(Q", i, "[Q", i,
              "$anon_user_id %in% Q1$anon_user_id,])", sep = "")
  eval(parse(text = Qx))
}

答案 2 :(得分:0)

这是一个例子,它解决了我认为你想要完成的事情的简化版本。

x1 = 34
x2 = 65
x3 = 87
x4 = 298
x5 = 384
x6 = 234

var.names = sapply(1:6, function(i){
    paste0("x", i)
})

var.values = sapply(varnames, get)

 #x1  x2  x3  x4  x5  x6 
 #34  65  87 298 384 234