簡體   English   中英

使用粘貼在R中編寫循環?

[英]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))] )

此進行比較的交點ij迭代,所以1,12,13,11,22,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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM