R

时间:2016-02-23 11:20:07

标签: r loops

我通常是目前使用R的枫用户,我在正确索引变量时遇到问题。

我想要定义2个向量,v1和v2,我想在v1中调用第n个元素。枫木很容易做到: v [1]:=某个向量,

然后命令调用第n个元素 V [1] [N]。 如何在R中完成?实际问题如下:

我有一个模拟的否定变量的序列M(比如长度为10,用k索引)。对于这些模拟变量中的每一个,我想构建长度为M [k]的向量X,其中条目由某个公式给出。所以我最终应该有10个不同的向量,每个向量都有不同的长度。我的错误代码看起来像这样

sims<-10
M<-rnegbin(sims, eks_2016_kasko*exp(-2.17173), 840.1746)
for(k in 1:sims){
                 x[k]<-rep(NA,M[k])
                 X[k]<-rep(NA,M[k])
for(i in 1:M[k]){x[k][i]<-runif(1,min=0,max=1)
                  if(x[k][i]>=0 & x[i]<=0.1056379){
                    X[k][i]<-rlnorm(1, 6.228244, 0.3565041)}
  else{
    X[k][i]<-rlnorm(1, 8.910837, 1.1890874)
  }
 }
}

错误似乎是x [k]不是变量的有效名称。有什么方法可以做到这一点吗?

非常感谢:)

2 个答案:

答案 0 :(得分:1)

我已经略微编辑了您的R脚本以使其正常工作并使其可重现。为此,我不得不假设eks_2016_kasko10的整数值。

require(MASS)
sims<-10

# Because you R is not zero indexed add one
M<-rnegbin(sims, 10*exp(-2.17173), 840.1746) + 1

# Create a list
x <- list()
X <- list()
for(k in 1:sims){
    x[[k]]<-rep(NA,M[k])
    X[[k]]<-rep(NA,M[k])
    for(i in 1:M[k]){
        x[[k]][i]<-runif(1,min=0,max=1)
    if(x[[k]][i]>=0 & x[[k]][i]<=0.1056379){
        X[[k]][i]<-rlnorm(1, 6.228244, 0.3565041)}
    else{
        X[[k]][i]<-rlnorm(1, 8.910837, 1.1890874)
    }
    }

这将有效,我认为你正在尝试做什么,但不是很好的R代码。我强烈建议使用lapply family而不是for循环,学习使用data.table和并行化,如果你需要扩展的话。另外,如果你想了解更多有关R中的索引和子集的信息Hadley Wickham有一个全面的细分here

希望这有帮助!

答案 1 :(得分:1)

让我先从几个评论开始,然后告诉您,如何使用R来解决您的问题。

  • 在R中,大多数情况下不需要使用for循环来为向量分配多个值。因此,例如,要使用均匀分布的随机变量填充长度为100的向量,您可以执行以下操作:

    set.seed(1234)
    x1 <- rep(NA, 100)
    for (i in 1:100) {
      x1[i] <- runif(1, 0, 1)
    }
    

    set.seed()用于设置随机种子,这样每次都会获得相同的结果。)这样做更简单(也更快):

    x2 <- runif(100, 0, 1)
    identical(x1, x2)
    ## [1] TRUE
    

    如您所见,结果完全相同。

  • x[k]<-rep(NA,M[k])不起作用的原因是x[k]确实不是R中的有效变量名。[用于索引,因此x[k]从向量k中提取元素x。由于您尝试将长度大于1的向量分配给单个元素,因此会出现错误。您可能想要使用的是一个列表,您将在下面的示例中看到。

因此,我将使用的代码代替您在帖子中提出的内容。请注意,我不确定我是否正确理解了您打算做什么,因此我还将在下面描述代码的作用。如果这符合您的意图,请告诉我。

# define M
library(MASS)
eks_2016_kasko <- 486689.1
sims<-10
M<-rnegbin(sims, eks_2016_kasko*exp(-2.17173), 840.1746)

# define the function that calculates X for a single value from M
calculate_X <- function(m) {
  x <- runif(m, min=0,max=1)
  X <- ifelse(x > 0.1056379, rlnorm(m, 6.228244, 0.3565041),
              rlnorm(m, 8.910837, 1.1890874))
}
# apply that function to each element of M
X <- lapply(M, calculate_X)

如您所见,该解决方案中没有循环。我最后会开始解释:

  • lapply用于将函数(calculate_X)应用于列表或向量的每个元素(此处为向量M)。它返回一个列表。所以,你可以得到,例如,带有X[[3]]的第三个向量(注意[[用于从列表中提取元素)。 X[[3]]的内容将是calculate_X(M[3])

  • 的结果
  • 函数calculate_X()执行以下操作:它创建m均匀分布的随机值的向量(请记住m遍历M的元素)并存储在x中。然后它创建一个包含日志正态分布随机变量的向量X。分布的参数取决于值x