R:在for循环中初始化/创建数据帧

时间:2016-07-18 14:09:14

标签: r for-loop dataframe

我想知道使用cbindrbind在for-loop中创建和修改数据框的最佳或最合适的方法是什么?对于第一次迭代,数据框没有列或行,因此 - 在下面的示例中 - cbind不起作用。仅针对第一种情况,我需要在for循环中使用if-else命令。是不是有更优雅的方式来改写下面的代码,即没有if-else?

mydat <- data.frame()

for (j in 1:10) {
  if (ncol(mydat) == 0)
    mydat <- data.frame(sample(x = j * 5, size = 20, replace = T))
  else
    mydat <- cbind(mydat, data.frame(sample(x = j * 5, size = 20, replace = T)))
}

colnames(mydat) <- sprintf("x%i", 1:10)

1 个答案:

答案 0 :(得分:3)

这是一种结合lapplydo.call(cbind, list)约定的简单方法,用于生成所需的data.frame。

set.seed(1234)
gendata <- function(x) {
  sample(x = x*5, size = 20, replace = T)
}
do.call(cbind, lapply(1:10, gendata))
#      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,]    1    4    9   18   24    2   27   21   20    24
# [2,]    4    4   10    1   12   17   33   40   26    18
# [3,]    4    2    5    7    4    9   35   13   20    31
# [4,]    4    1   10    1   14    7   33   20   11     4
# [5,]    5    3    5    5    5    5   18   15    4    48
# [6,]    4    9    8   15   23   10   10   26   29     2
# [7,]    1    6   11    7   10    5    9   30   20    43
# [8,]    2   10    8   11    8    4   18   23    4    32
# [9,]    4    9    4    2    5   14   18   40   37    16
# [10,]   3    1   12   12   23    2   12   24   15    38
# [11,]   4    5    2    3    5   22   34   18   35    32
# [12,]   3    3    5   18   23    4   23   10   27    50
# [13,]   2    4   11    1    4   29    5    4   32     7
# [14,]   5    6    8   16    4    4   15   35   20    45
# [15,]   2    2    3    2    3    7   33   10   16    41
# [16,]   5    8    8   11   13   28   17   40   35    42
# [17,]   2    3    8    8    8   29   32   25   20    42
# [18,]   2    3   12    2    1    9   21   40   26    37
# [19,]   1   10    3    7    8    4   23   16    6    50
# [20,]   2    9   13   14   19   24   31   23   14    32

修改

正如Konrad Rudolph指出的那样,我提供的结果是一个矩阵而不是data.frame。只需使用as.data.frame转换矩阵:

set.seed(1234)
gendata <- function(x) {
  sample(x = x*5, size = 20, replace = T)
}
dat <- as.data.frame(do.call(cbind, lapply(1:10, gendata)))
names(dat) <- sprintf("x%i", 1:10)
head(dat)
#   x1 x2 x3 x4 x5 x6 x7 x8 x9 x10
# 1  1  4  9 18 24  2 27 21 20  24
# 2  4  4 10  1 12 17 33 40 26  18
# 3  4  2  5  7  4  9 35 13 20  31
# 4  4  1 10  1 14  7 33 20 11   4
# 5  5  3  5  5  5  5 18 15  4  48
# 6  4  9  8 15 23 10 10 26 29   2