通过使用单个向量在data.table中通过引用更新多列

时间:2018-07-09 15:42:29

标签: r data.table

我正在尝试通过使用函数的输出引用data.table的多列进行更新。例如,我设置了一个伪函数和一个伪dt:

exampleDT <- data.table(1:6, 0,0,0,0,0,0,0,0)
exampleDF <- as.data.frame(exampleDT) 
exampleFUN <- function(x){seq(x, x+7)}

预期输出:

for(i in 1:NROW(exampleDF)){
exampleDF[i, 2:9] <- exampleFUN(i)
}  

  V1 V2 V3 V4 V5 V6 V7 V8 V9
1  1  1  2  3  4  5  6  7  8
2  2  2  3  4  5  6  7  8  9
3  3  3  4  5  6  7  8  9 10
4  4  4  5  6  7  8  9 10 11
5  5  5  6  7  8  9 10 11 12
6  6  6  7  8  9 10 11 12 13

请注意,我的DT有数百万行,如果您能指出一个快速的解决方案,我将不胜感激。

EDIT1: 我提供的功能只是一个示例,真正的功能更复杂。它会考虑边界,在栅格中查找相邻像元。第一列包含我想要其邻居的单元格ID。理想情况下,代码应类似于:

for(i in 1:NROW(exampleDT)) {
  set(exampleDT, i=i, j=2:9, value=exampleFUN(exampleDT[i, V1]))
}

EDIT2: 我打算使用的实际功能:

neighbourF <- function(CellID, cols, ncell) {

  if(CellID == 1) { # Top right corner
      return(c(NA, NA, NA, CellID + cols , CellID + (cols + 1) , CellID + 1, NA, NA))

  } else if(CellID %in% 2:(cols-1)) { # Top row
      return(c(NA, CellID - 1 , CellID + (cols - 1) , CellID + cols , CellID + (cols + 1) , CellID + 1, NA, NA))

  } else if(CellID == cols) { # Top right corner
      return(c(NA, CellID - 1 , CellID + (cols - 1) , CellID + cols, NA, NA, NA, NA))

  } else if(CellID %in% seq(cols+1, ncell-cols, cols)) { # Left column
      return(c(NA, NA, NA, CellID + cols , CellID + (cols + 1) , CellID + 1 , CellID - (cols - 1) , CellID - cols))

  } else if(CellID == ncell-cols+1) { # Bottom left corner
      return(c(NA, NA, NA, NA, NA, CellID + 1 , CellID - (cols - 1) , CellID - cols))

  } else if(CellID %in% (ncell-cols+2):(ncell-1)) { # Bottom row
      return(c(CellID - (cols + 1) , CellID - 1 , NA, NA, NA, CellID + 1 , CellID - (cols - 1) , CellID - cols))

  } else if(CellID == ncell) { # Bottom right corner
      return(c(CellID - (cols + 1) , CellID - 1 , NA, NA, NA, NA, NA, CellID - cols))  

  } else if(CellID %in% seq(2*cols, ncell-cols, cols)) { # Right column
      return(c(CellID - (cols + 1) , CellID - 1 , CellID + (cols - 1) , CellID + cols , NA, NA, NA, CellID - cols))

  } else {
      return(c(CellID - (cols + 1) , CellID - 1 , CellID + (cols - 1) , CellID + cols , CellID + (cols + 1) , CellID + 1 , CellID - (cols - 1) , CellID - cols))

  }

}

欢呼

1 个答案:

答案 0 :(得分:0)

可能的解决方案:

# option 1
exampleDT[, (2:9) := .SD + outer(.I, 0:7, `+`), .SDcols = 2:9][]

# option 2
exampleDT[, (2:9) := .SD + outer(1:nrow(exampleDT), 0:7, `+`), .SDcols = 2:9][]

给出:

> exampleDT
   V1 V2 V3 V4 V5 V6 V7 V8 V9
1:  1  1  2  3  4  5  6  7  8
2:  2  2  3  4  5  6  7  8  9
3:  3  3  4  5  6  7  8  9 10
4:  4  4  5  6  7  8  9 10 11
5:  5  5  6  7  8  9 10 11 12
6:  6  6  7  8  9 10 11 12 13