我尝试使用freq()计算R中栅格像素值的频率/数量。 创建两个示例栅格进行比较:
public string JSONSelect(string Json, string JsonPath)
{
string jsonResult = string.Empty;
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter json = new JsonTextWriter(sw))
{
json.Formatting = Newtonsoft.Json.Formatting.None;
JToken res = JToken.Parse(Json).SelectToken(JsonPath); //http://www.newtonsoft.com/json/help/html/SelectToken.htm
if (res != null)
{
switch (res.Type)
{
case JTokenType.String:
sb.Append(((JValue)res).ToString());
break;
case JTokenType.Null:
break;
default:
res.WriteTo(json); //<-----------here!
break;
}
}
}
jsonResult = sb.ToString();
return jsonResult;
}
使用freq()获取像素数
library(raster)
RastSmall <- raster(nrow=70, ncol=70)
RastBig <- raster(nrow=7000, ncol=7000)
set.seed(0)
RastSmall[] <- round(runif(1:ncell(r_hr), 1, 5))
RastBig[] <- round(runif(1:ncell(r_hr), 1, 5))
然而,它是一个相当大的文件,需要很长时间,即长达数小时。在R中有更快的方式吗? 这里是小型和大型栅格的速度差异:
freq(RastSmall)
value count
[1,] 1 6540000
[2,] 2 12150000
[3,] 3 12140000
[4,] 4 11720000
[5,] 5 6450000
有没有办法加快速度?或者可以使用像gdal tools这样的命令行来完成吗?
答案 0 :(得分:0)
我上周完成了这一点,但是我无法在R中找到其他更快捷的方法。我已经尝试通过调用{{1}来使用rqgis
包来做到这一点。 GRASS的。它工作但比R本机功能慢。也许你会有更好的运气。这是我的草代码,如果您想尝试它:
r.report
答案 1 :(得分:0)
不是一个惊人的保存,但如果你从你的栅格中获得值,然后运行base :: table函数,它可以节省大约20%。我的光栅是500万个细胞。
# read in raster to obtain frequency table
r <- raster("./path/myraster.tif")
# perform tests; traditional freq() vs. getValues() & table()
require(microbenchmark)
mbm <- microbenchmark(
Freq = {freqf <- freq(r,useNA="no");
freq.df <- data.frame(CODE=freqf[,1], N=freqf[,2]},
GetVals = {v <- getValues(r);
vt <- table(v);
getval.df <- data.frame(CODE=as.numeric(names(vt)),N=as.numeric(as.matrix(vt)))},
times=5
)
mbm
Unit: seconds
expr min lq mean median uq max neval
Freq 191.1649 191.8001 198.8567 192.5256 193.0986 225.6942 5
GetVals 153.5552 154.8776 156.9173 157.0539 159.0400 160.0598 5
# check the routines have identical results
identical(freq.df,getval.df)
[1] TRUE
我猜是有点拯救
(N.B.我制作数据帧的原因是我继续处理频率分析产生的数据)
答案 2 :(得分:0)
我认为最有效的计算方法是使用GDAL中的GetHistogram( )。不幸的是,我找不到在R中使用它的方法。最接近的方法是在R中使用gdalUtilities::gdalinfo
,并使用标志-hist或hist = TRUE,但将计算限制在0-255之间。
另一种选择是使用rasterDT::freqDT
,它比常规选项要快。这里是一个例子:
library(gdalUtilities)
library(raster)
library(rasterDT)
library(microbenchmark)
RastBig <- raster(nrow=7000, ncol=7000)
set.seed(0)
RastBig[] <- round(runif(1:ncell(RastBig), 1, 5))
writeRaster(RastBig, filename = 'C:/temp/RastBig.tif')
mbm <- microbenchmark(times = 50,
freq1 = freq(RastBig),
freq2 = table(RastBig[]),
freq3 = freqDT(RastBig),
freq4 = ({
gdalLog <- capture.output(gdalUtilities::gdalinfo(datasetname = 'C:/temp/RastBig.tif', hist = TRUE));
(bucxml <- as.numeric(sub('buckets.+', '', grep('buckets ', gdalLog, value = TRUE))));
(minxml <- as.numeric(gsub('.+from | to.+', '', grep('buckets ', gdalLog, value = TRUE)) ));
(maxxml <- as.numeric(gsub('.+to |:', '', grep('buckets ', gdalLog, value = TRUE))));
(histxml <- as.numeric(strsplit(split = '[[:space:]]', gsub("^ |^ ", "", gdalLog[grep('buckets', gdalLog)+1]))[[1]]));
labs <- seq(from = minxml, to = maxxml, length.out = bucxml);
df <- data.frame(labs, nwlab = c(ceiling(labs[1]),
round(labs[2:(bucxml-1)]),
floor(labs[bucxml])),
val = histxml);
hist <- aggregate(df$val, by = list(df$nwlab), sum)})
)
结果:
> freq1
value count
[1,] 1 6127755
[2,] 2 12251324
[3,] 3 12249376
[4,] 4 12248938
[5,] 5 6122607
> freq2
1 2 3 4 5
6127755 12251324 12249376 12248938 6122607
> freq3
ID freq
1: 1 6127755
2: 2 12251324
3: 3 12249376
4: 4 12248938
5: 5 6122607
> freq4
Group.1 x
1 1 6127755
2 2 12251324
3 3 12249376
4 4 12248938
5 5 6122607
Unit: milliseconds
expr min lq mean median uq max neval
freq1 58628.486301 59100.539302 59400.304887 59383.913701 59650.412 60841.3975 50
freq2 55912.170401 56663.025202 56954.032395 56919.905051 57202.001 58307.9500 50
freq3 3785.767301 4006.858102 4288.699531 4292.447250 4536.382 4996.0598 50
freq4 7.892201 8.883102 9.255641 9.154001 9.483 15.6072 50
编辑:使用此方法比方法3快得多
rB <- raster('C:/temp/RastBig.tif')
freq3B <- freqDT(rB)