如何永久更改 R 中的向量?
How do I permanently change a vector in R?
我正在尝试模拟一场锦标赛,在该锦标赛中,每一轮从 13 名选手中随机选择两名选手进行比赛,他们的 Elo rating(衡量他们的相对技能水平的指标)会得到更新。每个玩家都有真正的基础技能水平 true.rating
,在锦标赛期间,我在每一轮之后存储他们的评分,我试图更新 current.ratings
并将每次迭代存储在 ratings.matrix
中。这是我的代码,用 R markdown
编写
true.ratings <- seq(from = -2, to = 2, length.out = 13)
current.ratings <- seq(from = -2, to = 2, length.out = 13)
ratings.matrix <- matrix(nrow = 13, ncol = 10000)
i.wins <- function(i, j, p) {
i.wins <- rbinom(1, 1, p)
return(i.wins)
}
update <- function (K, i, j) {
R.i <- true.ratings[i]
R.j <- true.ratings[j]
probability_i.wins <- 1/(1 + exp(R.j - R.i))
probability_j.wins <- 1 - probability_i.wins
winner.is.i <- as.logical(i.wins(i, j, probability_i.wins))
if (winner.is.i) {
replace(current.ratings, i , current.ratings[i] + K*(1-probability_i.wins))
replace(current.ratings, j, current.ratings[j] -K*probability_j.wins)
}
if (!winner.is.i) {
current.ratings[i] <- current.ratings[i] -K*probability_i.wins
current.ratings[j] <- current.ratings[j] + K*(1-probability_j.wins)
}
return(current.ratings)
}
match <- function(K) {
ij <- sample(1:13, 2, replace = F)
i <- ij[1]
j <- ij[2]
return(update(K, i, j))
}
tournament <- function(K) {
current.ratings <- match(K)
for (j in 1:10000) {
ratings.matrix[, j] <- match(K)
}
return(ratings.matrix)
}
ratings.matrix <- tournament(K = 0.01)
评分方法会在每一轮比赛后根据玩家 i
和玩家 j
的当前评分进行更新。但是,当两个不同的玩家进行下一轮比赛时,当前玩家 i 和 j 的评分将回到原来的 true.rating
值。我怀疑这与我没有正确更新我的 current.rating
矩阵向量有关。
这是我的第一个堆栈溢出 post,我也是 R 的新手。欢迎任何其他关于我如何改进的反馈:)
R 努力成为一种函数式语言,这意味着函数影响父环境中事物的唯一方式是通过 return 值。如果你想改变一个属于函数之外的某个环境的值,你需要用 R 的方式来做。
通常的做法:
Return current.ratings
并在顶层显式覆盖它。换句话说,你的函数 tournament()
需要 return 一个包含 current.ratings
和 ratings.matrix
的列表,然后你需要在顶层显式覆盖这两个变量环境(在你的函数调用之后)。
您需要将环境本身作为参数传递给函数。这是 R 的引用传递方式。例如
tournament <- function(K, myenv){
myenv$current.ratings <- match(K)
for (j in 1:10000) {
ratings.matrix[, j] <- match(K)
}
return(ratings.matrix)
}
ratings.matrix <- tournament(K = 0.01, myenv=environment())
</pre>
请注意,您也可以在您的案例中使用令人厌恶的 <<-
超赋值运算符,但我没有将其作为实际解决方案提及,因为我不想被任何烂番茄击中。
我正在尝试模拟一场锦标赛,在该锦标赛中,每一轮从 13 名选手中随机选择两名选手进行比赛,他们的 Elo rating(衡量他们的相对技能水平的指标)会得到更新。每个玩家都有真正的基础技能水平 true.rating
,在锦标赛期间,我在每一轮之后存储他们的评分,我试图更新 current.ratings
并将每次迭代存储在 ratings.matrix
中。这是我的代码,用 R markdown
true.ratings <- seq(from = -2, to = 2, length.out = 13)
current.ratings <- seq(from = -2, to = 2, length.out = 13)
ratings.matrix <- matrix(nrow = 13, ncol = 10000)
i.wins <- function(i, j, p) {
i.wins <- rbinom(1, 1, p)
return(i.wins)
}
update <- function (K, i, j) {
R.i <- true.ratings[i]
R.j <- true.ratings[j]
probability_i.wins <- 1/(1 + exp(R.j - R.i))
probability_j.wins <- 1 - probability_i.wins
winner.is.i <- as.logical(i.wins(i, j, probability_i.wins))
if (winner.is.i) {
replace(current.ratings, i , current.ratings[i] + K*(1-probability_i.wins))
replace(current.ratings, j, current.ratings[j] -K*probability_j.wins)
}
if (!winner.is.i) {
current.ratings[i] <- current.ratings[i] -K*probability_i.wins
current.ratings[j] <- current.ratings[j] + K*(1-probability_j.wins)
}
return(current.ratings)
}
match <- function(K) {
ij <- sample(1:13, 2, replace = F)
i <- ij[1]
j <- ij[2]
return(update(K, i, j))
}
tournament <- function(K) {
current.ratings <- match(K)
for (j in 1:10000) {
ratings.matrix[, j] <- match(K)
}
return(ratings.matrix)
}
ratings.matrix <- tournament(K = 0.01)
评分方法会在每一轮比赛后根据玩家 i
和玩家 j
的当前评分进行更新。但是,当两个不同的玩家进行下一轮比赛时,当前玩家 i 和 j 的评分将回到原来的 true.rating
值。我怀疑这与我没有正确更新我的 current.rating
矩阵向量有关。
这是我的第一个堆栈溢出 post,我也是 R 的新手。欢迎任何其他关于我如何改进的反馈:)
R 努力成为一种函数式语言,这意味着函数影响父环境中事物的唯一方式是通过 return 值。如果你想改变一个属于函数之外的某个环境的值,你需要用 R 的方式来做。
通常的做法:
Return
current.ratings
并在顶层显式覆盖它。换句话说,你的函数tournament()
需要 return 一个包含current.ratings
和ratings.matrix
的列表,然后你需要在顶层显式覆盖这两个变量环境(在你的函数调用之后)。您需要将环境本身作为参数传递给函数。这是 R 的引用传递方式。例如
tournament <- function(K, myenv){ myenv$current.ratings <- match(K) for (j in 1:10000) { ratings.matrix[, j] <- match(K) } return(ratings.matrix) } ratings.matrix <- tournament(K = 0.01, myenv=environment()) </pre>
请注意,您也可以在您的案例中使用令人厌恶的
<<-
超赋值运算符,但我没有将其作为实际解决方案提及,因为我不想被任何烂番茄击中。