我猜我有一个简单的解决方案,但我遇到了一些麻烦.
我试图转换以下map对象:
require(maps)
usa <- map("state")
Run Code Online (Sandbox Code Playgroud)
SpatialPolygon使用map2SpatialPolygons函数进入对象:
require(maptools)
usa.sp <- map2SpatialPolygons(usa, IDs=usa$names,proj4string=CRS("+proj=longlat"))
Run Code Online (Sandbox Code Playgroud)
我一直收到以下错误:
Error in map2SpatialPolygons(usa, IDs = usa$names, proj4string = CRS("+proj=longlat")) :
map and IDs differ in length
Run Code Online (Sandbox Code Playgroud)
经过一些研究,看起来ID的长度为63,并且map在应用函数后对象的长度为169 .NAmat2xyList(cbind(map$x, map$y))(我找不到源代码).
有人有主意吗?这是usa地图对象的结构:
> str(usa)
List of 4
$ x : num [1:1705] -88.4 -88.1 -88 -87.9 -87.8 ...
$ y : num [1:1705] 30.4 30.4 30.8 30.6 30.3 ...
$ range: num [1:4] -124.7 -67 25.1 49.4
$ names: …Run Code Online (Sandbox Code Playgroud) 我试图从两个较小的数据集中模拟一个新的数据集.对我来说,在最终数据集中保持这些较小数据集的边际计数非常重要.希望这个可重复的例子可以解释我的意思.
library(data.table) # 1.10.5
set.seed(123)
meanVal <- 40
Run Code Online (Sandbox Code Playgroud)
在这里,我模拟一些年龄和性别数据.每个位置将始终具有2个性别级别和100个年龄级别.
demoDat <- CJ(with(CJ(letters,letters[1:5]), paste0(V1,V2)), c("M","F"), 0:99)
setnames(demoDat, c("Location","Gender","Age"))
demoDat[, Val := rpois(.N, meanVal)]
Location Gender Age Val
1: aa F 0 36
2: aa F 1 47
3: aa F 2 29
---
25998: ze M 97 45
25999: ze M 98 38
26000: ze M 99 39
Run Code Online (Sandbox Code Playgroud)
此代码模拟时间数据维度.在这种情况下,日期按周分隔,但实际数据不必遵循这种一致性.几周可能会丢失.
timeDat <- with(demoDat, CJ(unique(Location), seq(from=as.Date("2016-01-01"),by=7,length.out = 52)))
setnames(timeDat, c("Location","Date"))
totals <- demoDat[, .(Val=sum(Val)), by=.(Location)]
timeDat[totals, Val := rmultinom(1:.N, i.Val, …Run Code Online (Sandbox Code Playgroud) 我有一个结构如下的数据集:
data <- data.table(ID=1:10,Tenure=c(2,3,4,2,1,1,3,4,5,2),Var=rnorm(10))
ID Tenure Var
1: 1 2 -0.72892371
2: 2 3 -1.73534591
3: 3 4 0.47007030
4: 4 2 1.33173044
5: 5 1 -0.07900914
6: 6 1 0.63493316
7: 7 3 -0.62710577
8: 8 4 -1.69238758
9: 9 5 -0.85709328
10: 10 2 0.10716830
Run Code Online (Sandbox Code Playgroud)
我需要复制每一行N = Tenure次.例如,我需要复制第一行2次(因为Tenure = 2.
我需要我的转换数据集如下所示:
setkey(data,ID)
print(data[,.(ID=rep(ID,Tenure))][data][, Indx := 1:.N, by=ID])
ID Tenure Var Indx
1: 1 2 -0.7289237 1
2: 1 2 -0.7289237 2
3: 2 3 -1.7353459 …Run Code Online (Sandbox Code Playgroud) 我有几十万个非常小的.dat.gz文件,我想以最有效的方式读入R.我在文件中读取然后立即聚合并丢弃数据,因此我不担心在接近流程结束时管理内存.我只是想加快瓶颈,这恰好是解压缩和读取数据.
每个数据集由366行和17列组成.这是我目前所做的可重复的例子:
构建可重现的数据:
require(data.table)
# Make dir
system("mkdir practice")
# Function to create data
create_write_data <- function(file.nm) {
dt <- data.table(Day=0:365)
dt[, (paste0("V", 1:17)) := lapply(1:17, function(x) rnorm(n=366))]
write.table(dt, paste0("./practice/",file.nm), row.names=FALSE, sep="\t", quote=FALSE)
system(paste0("gzip ./practice/", file.nm))
}
Run Code Online (Sandbox Code Playgroud)
以下是代码申请:
# Apply function to create 10 fake zipped data.frames (550 kb on disk)
tmp <- lapply(paste0("dt", 1:10,".dat"), function(x) create_write_data(x))
Run Code Online (Sandbox Code Playgroud)
到目前为止,这是我最有效的代码来读取数据:
# Function to read in files as fast as possible
read_Fast <- function(path.gz) {
system(paste0("gzip -d ", path.gz)) # Unzip …Run Code Online (Sandbox Code Playgroud) 随着时间的推移,我已经习惯了data.table滚动连接的非常有用的功能r.这些利用了LOCF(最后观察结果)的操作.不幸的是,我被迫在一个我不太熟悉的环境中工作(使用postgres).SQL中是否有类似的操作(具体postgres)?
这是我拥有的一个例子和我想要的输出:
这是我的第一张桌子
dt1 = data.table(Date=seq(from=as.Date("2013-01-03"),
to=as.Date("2013-06-27"), by="1 day"),key="Date")[, ind:=.I]
Date ind
1: 2013-01-03 1
2: 2013-01-04 2
3: 2013-01-05 3
4: 2013-01-06 4
5: 2013-01-07 5
---
172: 2013-06-23 172
173: 2013-06-24 173
174: 2013-06-25 174
175: 2013-06-26 175
176: 2013-06-27 176
Run Code Online (Sandbox Code Playgroud)
这是我的第二张桌子
dt2 = data.table(Date=seq(from=as.Date("2013-01-01"),
to=as.Date("2013-06-30"), by="1 week"),key="Date")
Date
1: 2013-01-01
2: 2013-01-08
3: 2013-01-15
4: 2013-01-22
5: 2013-01-29
---
22: 2013-05-28
23: 2013-06-04
24: 2013-06-11
25: 2013-06-18 …Run Code Online (Sandbox Code Playgroud) 我想通过矢量化或使用Data.table或其他方法来提高for循环的速度.我必须在1,000,000行上运行代码,我的代码非常慢.
代码是相当不言自明的.我在下面提供了一个解释,以防万一.我已经包含了函数的输入和输出.希望你能帮助我更快地完成这项功能.
我的 目标是将矢量"Volume"分区,其中每个bin等于100份.向量"卷"包含交易的股票数量.这是它的样子:
head(Volume, n = 60)
[1] 5 3 1 5 3 1 1 1 1 1 1 1 18 1 1 18 2 7 13 2 7 13 3 2 1 1 3 2 1 1 1
[32] 1 6 6 1 1 1 1 1 1 1 1 18 2 1 1 2 1 14 18 2 1 1 2 1 14 1 1 9 5
Run Code Online (Sandbox Code Playgroud)
向量"binIdexVector"与"Volume"的长度相同,它包含bin号; 即前100个股票的每个元素得到数字1,接下来100个股票的每个元素得到数字2,接下来100个股票的每个元素得到数字3,依此类推.这是矢量的样子:
head(binIdexVector, n = 60)
[1] 1 1 …Run Code Online (Sandbox Code Playgroud) 假设我有以下样本数据集:
iris <- data.table(iris)[c(1:5,51:55,101:105), list(ID=.I, Species,Sepal.Length)]
Run Code Online (Sandbox Code Playgroud)
然后说我想计算组内行之间的绝对差异(在本例中Species).
iris[ , SL.Diff := c(NA,abs(diff(Sepal.Length))) , by = Species]
Run Code Online (Sandbox Code Playgroud)
此时,我有一个如下所示的数据集:
ID Species Sepal.Length SL.Diff
1: 1 setosa 5.1 NA
2: 2 setosa 4.9 0.2
3: 3 setosa 4.7 0.2
4: 4 setosa 4.6 0.1
5: 5 setosa 5.0 0.4
6: 6 versicolor 7.0 NA
Run Code Online (Sandbox Code Playgroud)
现在我想计算一个新变量Sepal.Length2,如果SL.Diff小于0.3的阈值,它将采用下一行的值.
iris[ , Sepal.Length2 := ifelse(SL.Diff < 0.3, iris[ID+1]$Sepal.Length, Sepal.Length)]
Run Code Online (Sandbox Code Playgroud)
这按照我想要的方式工作.但是,如果我想进行相同的比较,而不是采取下一行,我想采取前一行的值?
iris[ , Sepal.Length3 := ifelse(SL.Diff < 0.3, iris[ID-1]$Sepal.Length, Sepal.Length)]
Run Code Online (Sandbox Code Playgroud)
Sepal.Length3没有给出我期望的输出.谁知道我在这里做错了什么?
ID …Run Code Online (Sandbox Code Playgroud) 我一直在玩更新的data.table条件合并功能,它非常酷.我有一种情况,我有两个表,dtBig并且dtSmall,当这个条件合并发生时,两个数据集中有多个行匹配.有没有办法使用类似max或min多个匹配的函数聚合这些匹配?这是一个可重现的例子,试图模仿我想要完成的事情.
## docker run --rm -ti rocker/r-base
## install.packages("data.table", type = "source",repos = "http://Rdatatable.github.io/data.table")
Run Code Online (Sandbox Code Playgroud)
创建一个包含50行的"大"表(每个ID 10个值).
library(data.table)
set.seed(1L)
# Simulate some data
dtBig <- data.table(ID=c(sapply(LETTERS[1:5], rep, 10, simplify = TRUE)), ValueBig=ceiling(runif(50, min=0, max=1000)))
dtBig[, Rank := frank(ValueBig, ties.method = "first"), keyby=.(ID)]
ID ValueBig Rank
1: A 266 3
2: A 373 4
3: A 573 5
4: A 909 9
5: A 202 2
---
46: E 790 …Run Code Online (Sandbox Code Playgroud) 我一直在使用支持直接从 AWS S3 读取和写入的最新R arrow包 ( arrow_2.0.0.20201106)(这很棒)。
我在编写和读取自己的文件时似乎没有问题(见下文):
write_parquet(iris, "iris.parquet")
system("aws s3 mv iris.parquet s3://myawsbucket/iris.parquet")
df <- read_parquet("s3://myawsbucket/iris.parquet")
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试读取其中一个示例R arrow文件时,出现以下错误:
df <- read_parquet("s3://ursa-labs-taxi-data/2019/06/data.parquet")
Error in parquet___arrow___FileReader__ReadTable1(self) :
IOError: NotImplemented: Support for codec 'snappy' not built
Run Code Online (Sandbox Code Playgroud)
当我检查编解码器是否可用时,它看起来不是:
codec_is_available(type="snappy")
[1] FALSE
Run Code Online (Sandbox Code Playgroud)
任何人都知道一种使“活泼”编解码器可用的方法?
谢谢,迈克
############
感谢下面@Neal 的回答。这是为我安装所有需要的依赖项的代码。
Sys.setenv(ARROW_S3="ON")
Sys.setenv(NOT_CRAN="true")
install.packages("arrow", repos = "https://arrow-r-nightly.s3.amazonaws.com")
Run Code Online (Sandbox Code Playgroud) 我试图更好地掌握data.table包中的一些特殊变量是如何工作的.其中之一就是.BY声明.我没有看到很多人使用它的例子,但是文档暗示在绘图中很有用.
例如,下面的代码似乎工作得很好(显示每个物种的图,并为每个图分配正确的标题)data.table 1.9.3:
iris <- data.table(iris)
iris[,plot(Sepal.Length ~ Sepal.Width, main = unlist(.BY)), by = Species]
Run Code Online (Sandbox Code Playgroud)
虽然此代码不符合我的意图:
iris[ , plot(Sepal.Length ~ Sepal.Width, main = .BY), by = Species]
Run Code Online (Sandbox Code Playgroud)
为什么这两个不同?从评论来看,它似乎不是一个问题data.table 1.9.2.在其他方面使用该.BY声明可能有用吗?与.EACHI声明相比,这有何不同?
r ×10
data.table ×7
performance ×3
apache-arrow ×1
for-loop ×1
h2o ×1
maps ×1
memory ×1
postgresql ×1
r-maptools ×1
r-sp ×1
rcpp ×1
snappy ×1