[英]Using paste to write a loop in 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,])
與R中的許多操作一樣,將數據幀包裝在列表中也更加容易。
Q_all <- list(Q1,Q2,Q3)
首先,不是使用nrow
,而是為什么不直接測量%in%
向量中有多少個TRUE
值。
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))] )
此進行比較的交點i
和j
迭代,所以1,1
, 2,1
, 3,1
, 1,2
, 2,2
等。 現在,我可以將其放入一個矩陣。 默認情況下,在R中的矩陣和數組中,矢量被假定為以列為主的順序(第一個維變化最快,最后一個維變化最快)。
TookQuizX <- matrix(unlist(tmp), nrow = length(anon_user_ids))
# [,1] [,2] [,3]
# [1,] 4 2 2
# [2,] 2 5 3
# [3,] 2 3 5
您需要做兩件事。 首先,您需要重新創建要運行的命令:
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))
}
這是一個示例,它解決了我認為您要完成的工作的簡化版本。
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.