【问题标题】:R loop to create data frames with 2 countersR循环用2个计数器创建数据帧
【发布时间】:2019-04-26 07:44:00
【问题描述】:

我想要的是创建 60 个数据框,每个数据框有 500 行。我尝试了下面的代码,虽然我没有收到任何错误,但我没有得到数据帧。但是,当我在 as.data.frame 上执行视图时,我得到了视图,但在我的环境中没有数据框。我已经尝试了三天的各种版本的代码:

getDS <- function(x){
  for(i in 1:3){
    for(j in 1:30000){
      ID_i <- data.table(x$ID[j: (j+500)])
    }
  }
  as.data.frame(ID_i)
}

getDS(DATASETNAME)

【问题讨论】:

  • 如果是60个数据帧,j索引应该不同。

标签: r loops dataframe for-loop


【解决方案1】:

我们可以使用outer(在一个小例子上)

out1 <- c(outer(1:3, 1:3, Vectorize(function(i, j) list(x$ID[j:(j + 5)]))))
lapply(out1, as.data.table)

--

OP 函数中的问题是,在循环内部,ID_i 每次都会更新,即它没有被存储。为此,我们可以初始化一个list 然后存储它

getDS <- function(x) {
      ID_i <- vector('list', 3)
      for(i in 1:3) {
           for(j in 1:3) {
           ID_i[[i]][[j]] <- data.table(x$ID[j:(j + 5)])
          }
        }
      ID_i
    }

do.call(c, getDS(x))       

数据

x <- data.table(ID = 1:50)

【讨论】:

  • 非常感谢@akrun!!
  • 我正在获取列表,但不确定如何将它们解压缩到不同的数据帧中。
  • @Divs。最好将其保存在list 中,而不是在全局环境中创建不同的对象。但是,如果你想拥有不同的对象(不推荐)。 lst1 &lt;- do.call(c, getDS(x)); names(lst1) &lt;- paste0("data", seq_along(lst1)); list2env(lst1, envir = .GlobalEnv)。现在您可以在您的全局环境中查看data1data2。但是,正如我所说,使用lists of data.frame 更容易
  • 谢谢@akrun。我希望它们作为数据框的原因是因为我需要在它们上编写 write.csv()。
【解决方案2】:

我不确定描述是否与代码匹配,所以我有点不确定想要的结果是什么。也就是说,拆分data.table 通常没有帮助,因为内置的副处理使得它变得不必要。如果出于某种原因您确实想拆分为data.tables 列表,您可能会考虑类似于

getDS <- function(x, n=5, size = nrow(x)/n, column = "ID", reps = 3) {
    x <- x[1:(n*size), ..column]
    index <- rep(1:n, each = size) 
    replicate(reps, split(x, index),
              simplify = FALSE)
}

getDS(data.table(ID = 1:20), n = 5)

【讨论】:

  • 谢谢@Ista。我收到有关未找到列的错误: eval 中的错误(expr,envir,enclos):找不到对象'..column'
  • @Divs 你可能有一个旧版本的data.table。更新到最新版本(当前为1.11.8)。
猜你喜欢
  • 2020-05-25
  • 2016-04-22
  • 1970-01-01
  • 1970-01-01
  • 2021-04-15
  • 1970-01-01
  • 2021-12-22
  • 2023-03-19
  • 2014-08-05
相关资源
最近更新 更多