我有一个通常看起来像这样的数据框

df.data <- data.frame(x=sample(1:9, 10, replace = T), y=sample(1:9, 10, replace=T), vx=sample(-1:1, 10, replace=T), vy=sample(-1:1, 10, replace=T))

x 和 y 是位置。 vx 和 vy 是二维向量的 x, y 值。我想根据 x 和 y 值获取此数据框和“bin”,但对 vx 和 vy 执行计算。此函数执行此操作,但它使用的循环对于我的数据集来说太慢了。
slowWay <- function(df)
{
    df.bin <- data.frame(expand.grid(x=0:3, y=0:3, vx=0, vy=0, count=0))

    for(i in 1:nrow(df))
    {
        x.bin <- floor(df[i, ]$x / 3)
        y.bin <- floor(df[i, ]$y / 3)
        print(c(x.bin, y.bin))

        df.bin[df.bin$x == x.bin & df.bin$y == y.bin, ]$vx = df.bin[df.bin$x == x.bin & df.bin$y == y.bin, ]$vx + df[i, ]$vx
        df.bin[df.bin$x == x.bin & df.bin$y == y.bin, ]$vy = df.bin[df.bin$x == x.bin & df.bin$y == y.bin, ]$vy + df[i, ]$vy
        df.bin[df.bin$x == x.bin & df.bin$y == y.bin, ]$count = df.bin[df.bin$x == x.bin & df.bin$y == y.bin, ]$count + 1
    }

    return(df.bin)
}

这种类型的 2D 分箱是否可以以非循环方式进行?

最佳答案

这是另一种更快的方法,包括未填充的垃圾箱组合:

fasterWay <- function(df.data) {
  a1 <- aggregate(df.data[,3:4], list(x=floor(df.data$x/3), y=floor(df.data$y/3)), sum)
  a2 <- aggregate(list(count=rep(NA,nrow(df.data))), list(x=floor(df.data$x/3), y=floor(df.data$y/3)), length)
  result <- merge(expand.grid(y=0:3,x=0:3), merge(a1,a2), by=c("x","y"), all=TRUE)
  result[is.na(result)] <- 0
  result <- result[order(result$y, result$x),]
  rownames(result) <- NULL
  result
}

它给了我:
   x y vx vy count
1  0 0  0  0     1
2  0 1  0  0     0
3  0 2 -1 -1     1
4  0 3  0  0     0
5  1 0 -1 -1     1
6  1 1  0  0     0
7  1 2  0  0     0
8  1 3 -1  0     2
9  2 0 -1 -1     1
10 2 1  0  0     0
11 2 2 -1  1     2
12 2 3  0  0     1
13 3 0  0  0     0
14 3 1  0  0     0
15 3 2 -1  0     1
16 3 3  0  0     0

关于R 使用二次复杂计算对数据框进行 2D 分箱,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15303692/

10-12 17:35
查看更多