快速替换R中数据帧中的值

时间:2012-10-11 09:03:10

标签: r replace dataframe

我有一个150,000行的数据框,其中2,000列包含值,有些是负数。 我将这些负值替换为0,但这样做非常慢(约60分钟或更长)。

df[df < 0] = 0

df[,1441:1453]看起来像(所有列/值都是数字):

  V1441 V1442 V1443 V1444 V1445 V1446 V1447 V1448 V1449 V1450 V1451 V1452 V1453
1     3     1     0     4     4    -2     0     3    12     5    17    34    27
2     0     1     0     7     0     0     0     1     0     0     0     0     0
3     0     2     0     1     2     3     6     1     2     1    -6     3     1
4     1     2     3     6     1     2     1    -6     3     1    -4     1     0
5     1     2     1    -6     3     1    -4     1     0     0     1     0     0
6     1     0     0     1     0     0     0     0     0     0     1     2     2

有没有办法加快这样的过程,例如我这样做的方式非常慢,而且有更快的方法吗? 感谢。

3 个答案:

答案 0 :(得分:30)

尝试将df转换为矩阵。

df <- data.frame(a=rnorm(1000),b=rnorm(1000))
m <- as.matrix(df)
m[m<0] <- 0
df <- as.data.frame(m)

答案 1 :(得分:22)

创建m时,原始方法和当前答案都会创建与df(或m<0)大小相同的对象(矩阵方法更快,因为内部复制较少将[<-[<-.data.frame

进行比较

您可以使用lapplyreplace,然后每次只查看一个向量或length (nrow(df)) 而不是复制那么多

df <- as.data.frame(lapply(df, function(x){replace(x, x <0,0)})

上面的代码应该非常有效。

如果您使用data.table,则data.frame方法的大部分内存(和)时间效率低下都会被删除。这对于像你这样的大数据情况来说是理想的。

library(data.table)
# this really shouldn't be 
DT <- lapply(df, function(x){replace(x, x <0,0)})
# change to data.table
setattr(DT, 'class', c('data.table','data.frame'))
# or 
# DT <- as.data.table(df, function(x){replace(x, x <0,0)})

您可以在所有列上设置键,然后通过引用替换小于0的键值

答案 2 :(得分:0)

另一个data.table答案可能更快,并且绝对应该消耗更少的内存。

library(data.table)
set.seed(108)
d = data.table(a=rnorm(1000),b=rnorm(1000))
set.colwise = function(x, i, j, value) {
  replace_dot_j = function(e, j) {
    if (is.symbol(e) && identical(e, as.symbol(".j"))) return(j)
    if (is.call(e)) {
      if (e[[1L]] == ".j") e[[1L]] = j
      for (i in seq_along(e)[-1L]) if (!is.null(e[[i]])) e[[i]] = replace_dot_j(e[[i]], j)
    }
    e
  }
  for (jj in j) eval(substitute(
    set(x, .i, .j, value),
    list(
      .i=replace_dot_j(substitute(i), jj),
      .j=jj
    )
  ))
  invisible(x)
}
d
set.colwise(d, i = which(d[[.j]] < 0), j = c("a","b"), value = 0)
d
.j参数中使用的

i符号进行迭代,并替换为j参数中的列。