【问题标题】:What is the most efficient way of converting a variable in a dataframe to a matrix in R?将数据框中的变量转换为 R 中的矩阵的最有效方法是什么?
【发布时间】:2018-03-21 10:09:42
【问题描述】:

我需要在 Windows 上的 R 3.4.1 中对数据框执行以下操作

  1. 按类别变量拆分数据框 -> 获取按该类别变量拆分的数据框列表(获取列表不是必需的,我就是这样做的)。
  2. 从拆分的数据框列表中提取一个变量。
  3. 将拆分后的变量组合到一个矩阵中。
  4. 转置矩阵。

目前我做这些操作如下:

t(sapply(split(df, df$date), function(x) x$avg_mean))

我希望这个操作更高效,即:

  1. 尽可能使用最少的内存,即尽可能不重复对象。我可能需要将它与 1.5 GB 数据帧一起使用。
  2. 快速处理大型数据帧。

在 R 中最合适/最有效的方法是什么?并行化也很受欢迎,但不是绝对必要的,因为我不确定我是否能够使用它。

如果您需要玩具数据框,请使用this

【问题讨论】:

  • 为什么不直接对感兴趣的变量使用 split 呢? (split(df$avg_mean, df$date))
  • 好吧,这已经是我没有想到的改进了。

标签: r dataframe data-manipulation


【解决方案1】:

最好的方法可能是按照 cmets 中建议的方向使用split(df$avg_mean, df$date) 并将结果绑定在一起。一个非常接近的第二个是将向量转换为矩阵,直接利用每个日期的观察次数在您的情况下必须是恒定的这一事实。一些方法及其速度如下:

library(microbenchmark)
library(data.table)

dat <- data.frame(date = rep(c('A', 'B', 'C'), each = 1000), 
                  avg_mean = rnorm(3000))

f1 <- function(dat) {
  t(sapply(split(dat, dat$date), function(x) x$avg_mean))
}

f2 <- function(dat) {
  matrix(dat$avg_mean, nrow=length(unique(dat$date)), byrow = T)
}

f3 <- function(dat) {
  do.call(rbind, split(dat$avg_mean, dat$date))
}

f4 <- function(DF) {
  DF = data.table(DF)
  DF[ , index := 1:.N, by=date]
  DF_trx = dcast(DF, index~date, value.var = "avg_mean")
  DF_trx$index=NULL
  t(as.matrix(DF_trx))
}

microbenchmark(f1(dat), f2(dat), f3(dat), f4(dat))
#> Unit: microseconds
#>     expr      min       lq      mean    median        uq       max neval
#>  f1(dat)  456.064  475.542  617.0032  489.9390  515.6205  4250.471   100
#>  f2(dat)  107.062  110.907  150.3135  117.6060  124.1925  2992.862   100
#>  f3(dat)   74.313   79.927  122.2712   84.4455   89.4250  2504.850   100
#>  f4(dat) 3797.694 3893.886 4563.4614 4021.6505 5053.5800 15757.085   100

看来do.call(rbind, split(dat$avg_mean, dat$date) 可能是你最好的选择。

【讨论】:

    【解决方案2】:

    我已经为每个组添加了一个索引和数据表转换功能以实现相同的功能。你应该使用数据表来提高效率

    DF = data.table(DF)
    DF[ , index := 1:.N, by=Col1]
    DF_trx = dcast(DF, index~Col1, value.var = "Col2")
    DF_trx$index=NULL
    as.matrix(DF_trx)
    

    【讨论】:

      猜你喜欢
      • 2013-06-08
      • 2018-10-06
      • 2011-05-29
      • 1970-01-01
      • 2013-03-05
      • 2019-02-18
      • 2012-09-04
      • 2019-09-20
      • 2014-12-13
      相关资源
      最近更新 更多