r - 如何用 data.table 替换 plyr::ddply
问题描述
我有一个聚合操作,它计算 R 中当前用plyr::ddply()
作主函数的多边形中的点,我需要按 2 个变量分组:dayofweek
和hour
. 它很慢,所以我想用更快的功能替换它,比如data.table
包中的东西。
代表
创建数据框
该操作的主要目标是获取点的数据框 df
,并使用包中的st_intersects()
方法sf
计算有多少点与多边形相交grid.sf
。
创建 DF 对象
library(sf)
library(tidyverse)
library(plyr)
df <- data.frame(X = seq(1,100,1),
dayofweek = rep(c("Sun", "Mon", "Tues", "Wed", "Thur"), 20),
hour = sample(seq(0, 23, 1), 100, replace = T),
lat = sample(seq(37.1234, 37.2345, 0.001), 100, replace = T),
lon = sample(seq(-122.5432, -122.4111, 0.001), 100, replace = T)
)
projcrs <- "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
df <- st_as_sf(x = df,
coords = c("lon", "lat"),
crs = projcrs)
创建 grid.sf 对象
# Function to create the grid we need
buildBaseGrid <- function(x) {
# create a 500m tesseract over these points
g <- st_make_grid(x, cellsize = 0.005)
# plot to make sure
# ggplot() +
# geom_sf(data = df.sf, size = 3) +
# geom_sf(data = g, alpha = 0)
#
# ggplot() +
# geom_sf(data = g, alpha = 0)
grid.sf <- st_sf(g)
# Need to expand by day of week
days <- c('SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA')
hours <- c('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12',
'13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23')
grid.sf <- expand.grid(g, days, hours)
grid.sf$id <- 1:nrow(grid.sf)
#### Clean up home grid
# Calc centroid
grid.sf <- grid.sf %>%
dplyr::mutate(center = sf::st_centroid(grid.sf$Var1))
# Parse out lat and lon
grid.sf <- grid.sf %>%
dplyr::mutate(lonn = sf::st_coordinates(grid.sf$center)[,1]) %>%
dplyr::mutate(latt = sf::st_coordinates(grid.sf$center)[,2])
# Create primary key field
grid.sf <- grid.sf %>%
dplyr::mutate(pkey = paste0(lonn,";",latt,";",Var2,";",Var3))
grid.sf <- st_as_sf(grid.sf)
return(grid.sf)
}
# Now build the grid.sf object
grid.sf <- buildBaseGrid(df)
plyr::ddply 的当前操作
# Create function to use in operation
myf <- function(x) {
x <- as.data.frame(x)
df <- df %>% dplyr::filter(dayofweek %in% x$Var2)
df <- df %>% dplyr::filter(hour %in% x$Var3)
x$count <- sf::st_intersects(x$Var1, df) %>% lengths()
x %>%
data.frame(x)
}
# Do the operation
output <- plyr::ddply(grid.sf, .(Var2, Var3), .fun = myf, .parallel = F) %>% as.data.frame()
这在我的机器上大约需要 4 秒,但我必须这样做数百次,所以它真的加起来了。
我尝试从 data.table 开始,但发现翻译很困难。这是我进行此data.table()
尝试的唯一(无效)代码:
test4 <- grid.sf[, .(test = myf()), by = key(grid.sf)]
所以,如果有办法将其转化ddply
为data.table
操作,我会被粉红色挠痒痒的,因为data.table
速度要快得多。
谢谢!
解决方案
推荐阅读
- ios - 如何过滤存储在数据库中的一组特定用户?
- django - 在 Docker 容器中运行时切换 Git 分支会导致权限错误
- css - 使用属性溢出可见的表中的ngx-dropdown可见性
- c# - 用 C# 中的常用破折号替换长破折号
- python - 当集合很大时搜索和检索包含部分字符串的集合元素
- javascript - page.$eval() 找不到选择器,选择器在控制台中工作
- python-3.x - 基于 Pandas 列第 2 部分的多个条件使用 pd.apply 进行分类分配
- swift - 如何撤销承诺?
- python - 带有连接的 Peewee 查询无法按预期工作
- javascript - Vue。v-if 中的动态变量