【问题标题】:Writing a for loop with the output as a data frame in R在 R 中编写一个将输出作为数据帧的 for 循环
【发布时间】:2017-01-27 08:47:53
【问题描述】:

我目前正在阅读“R for Data Science”一书。

我正在尝试解决这个练习题(21.2.1 Q1.4),但在开始 for 循环之前无法确定正确的输出。

编写一个 for 循环: 为 μ= -10、0、10 和 100 中的每一个生成 10 个随机法线。

就像书中前面的问题一样,我一直在尝试将其插入向量输出,但对于这个示例,我似乎需要将输出作为数据框?

这是我目前的代码:

values <- c(-10,0,10,100)
output <- vector("double", 10)

for (i in seq_along(values)) {
  output[[i]] <- rnorm(10, mean = values[[i]])
} 

我知道输出错误,但不确定如何在此处创建我需要的格式。非常感谢任何帮助。谢谢!

【问题讨论】:

  • 您可以使用lapplysapplyd1 &lt;- data.frame(lapply(values, function(x) rnorm(10, mean=x))); colnames(d1) &lt;- paste0("V", seq_along(values))
  • 您好,感谢您的解决方案。这确实有效,但最好也获得一个 for 循环解决方案,因为这是我目前打算提高的技能。谢谢!
  • 您首先创建一个空矩阵或列表,然后将值分配给它。即output &lt;- vector("list", 4);并在必要时使用您的代码和cbindrbind,即do.call(cbind, output)

标签: r for-loop


【解决方案1】:

有很多方法可以做到这一点。这是一个。请参阅内联 cmets。

set.seed(357) # to make things reproducible, set random seed

N <- 10 # number of loops

xy <- vector("list", N) # create an empty list into which values are to be filled

# run the loop N times and on each loop...
for (i in 1:N) {
  # generate a data.frame with 4 columns, and add a random number into each one
  # random number depends on the mean specified
  xy[[i]] <- data.frame(um10 = rnorm(1, mean = -10),
                        u0 = rnorm(1, mean = 0),
                        u10 = rnorm(1,  mean = 10),
                        u100 = rnorm(1, mean = 100))
}

# result is a list of data.frames with 1 row and 4 columns

# you can bind them together into one data.frame using do.call
# rbind means they will be merged row-wise
xy <- do.call(rbind, xy)

         um10         u0       u10      u100
1  -11.241117 -0.5832050 10.394747 101.50421
2   -9.233200  0.3174604  9.900024 100.22703
3  -10.469015  0.4765213  9.088352  99.65822
4   -9.453259 -0.3272080 10.041090  99.72397
5  -10.593497  0.1764618 10.505760 101.00852
6  -10.935463  0.3845648  9.981747 100.05564
7  -11.447720  0.8477938  9.726617  99.12918
8  -11.373889 -0.3550321  9.806823  99.52711
9   -7.950092  0.5711058 10.162878 101.38218
10  -9.408727  0.5885065  9.471274 100.69328

另一种方法是预先分配一个矩阵,添加值并将其强制转换为 data.frame。

xy <- matrix(NA, nrow = N, ncol = 4)

for (i in 1:N) {
  xy[i, ] <- rnorm(4, mean = c(-10, 0, 10, 100))
}

# notice that i name the column names post festum
colnames(xy) <- c("um10", "u0", "u10", "u100")
xy <- as.data.frame(xy)

【讨论】:

    【解决方案2】:

    由于这是一个学习问题,我不会直接提供解决方案。

    > values <- c(-10,0,10,100)
    > for (i in seq_along(values)) {print(i)} # Checking we iterate by position
    [1] 1
    [1] 2
    [1] 3
    [1] 4
    > output <- vector("double", 10) 
    > output # Checking the place where the output will be
     [1] 0 0 0 0 0 0 0 0 0 0
    > for (i in seq_along(values)) { # Testing the full code
    +     output[[i]] <- rnorm(10, mean = values[[i]])
    + } 
    Error in output[[i]] <- rnorm(10, mean = values[[i]]) : 
      more elements supplied than there are to replace
    

    如您所见,错误表明要放置的元素多于空间(每次迭代生成 10 个随机数(总共 40 个),而您只有 10 个空格。考虑使用允许存储多个值的数据格式每次迭代。 所以:

    > output <- ??
    > for (i in seq_along(values)) { # Testing the full code
    +     output[[i]] <- rnorm(10, mean = values[[i]])
    + } 
    > output # Should have length 4 and each element all the 10 values you created in the loop
    

    【讨论】:

    • 使用 akrun 上面的答案有效:输出
    • 是的,或者只是使用output &lt;- list()。您能否通过单击对勾来选择最有帮助的答案?这样问题就被标记为已解决:D
    【解决方案3】:
    # set the number of rows
    rows <- 10
    
    # vector with the values
    means <- c(-10,0,10,100)
    
    # generating output matrix
    output <- matrix(nrow = rows,
                 ncol = 4)
    
    # setting seed and looping through the number of rows
    set.seed(222)
    for (i in 1:rows){
      output[i,] <- rnorm(length(means),
                      mean=means)
    }
    
    #printing the output
    output
    

    【讨论】:

      猜你喜欢
      • 2020-03-25
      • 2020-03-29
      • 2015-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-26
      相关资源
      最近更新 更多