rasterFromXYZ missing value where TRUE/FALSE needed - r-raster

I have been having some strange error messages from the rasterFromXYZ function in the R raster package. Here is an example
library(raster)
xyz <- data.frame(x = c(5.463636, 5.481818, 5.5), y = c(51.42727, 51.42727, 51.42727), z = c(1.2,1.3,1.6))
r <- rasterFromXYZ(xyz)
##error
Error in if (nc > (2^31 - 1)) return(FALSE) :
missing value where TRUE/FALSE needed
In addition: Warning message:
In min(dy) : no non-missing arguments to min; returning Inf
##specifying the resolution as 1
r <- rasterFromXYZ(xyz, res = 1)
##different error
Error in rasterFromXYZ(xyz, res = 1) : x cell sizes are not regular
The x coordinates are perfectly regular. What am I doing wrong?

The x-coordinates are OK, but there is only one unique y-coordinate value. So there is no way to guess the vertical resolution.
xyz
# [,1] [,2] [,3]
#[1,] 5.463636 51.42727 1.2
#[2,] 5.481818 51.42727 1.3
#[3,] 5.500000 51.42727 1.6
If you set the resultion to 1 that does not match the x-coordinates, but you can do
rasterFromXYZ(xyz, res=c(NA, 1))
#class : RasterLayer
#dimensions : 1, 3, 3 (nrow, ncol, ncell)
#resolution : 0.018182, 1 (x, y)
#extent : 5.454545, 5.509091, 50.92727, 51.92727 (xmin, xmax, ymin, ymax)
#crs : NA
#source : memory
#names : layer
#values : 1.2, 1.6 (min, max)
The development version now gives a better error message:
r <- rasterFromXYZ(xyz)
#Error in rasterFromXYZ(xyz) : more than one unique y value needed

Related

How to remain same resolution and coordinate reference after calculation for raster in R

#####first import all files in a single folder as a list #####
rastlist <- list.files(path = ".", pattern='.tif$', all.files=TRUE, full.names=FALSE)
######load them in a stack ######
allrasters <- stack(rastlist)
input_stack1 <- stack(brick(allrasters))
####### create array #######
try <- array(input_stack1, dim=c(13056, 4846, 2,1))
####### replace -3000 with NA #######
try[try==-3000]<-NA
input_array<-aperm(try, c(2,1,3,4))
####### convert back #######
output_stack1<-stack(brick(array(input_array, c(4846, 13056, 2))))
>input_stack1
class : RasterStack
dimensions : 4846, 13056, 63269376, 2 (nrow, ncol, ncell, nlayers)
**resolution : 250, 250 (x, y)**
extent : -1253475, 2010525, 2211480, 3422980 (xmin, xmax, ymin, ymax)
**crs : +proj=utm +zone=51 +datum=WGS84 +units=m +no_defs**
names : MOSAIC_TMP_2019001.hdfout.250m_16_days_NDVI, MOSAIC_TMP_2019017.hdfout.250m_16_days_NDVI
min values : -3000, -3000
max values : 9996, 9996
>output_stack1
class : RasterStack
dimensions : 4846, 13056, 63269376, 2 (nrow, ncol, ncell, nlayers)
**resolution : 7.659314e-05, 0.0002063558 (x, y)**
extent : 0, 1, 0, 1 (xmin, xmax, ymin, ymax)
**crs : NA**
names : layer.1, layer.2
min values : -2000, -2000
max values : 9996, 9996
don't know why the resolution and crs in output_stack1 change. Can everyone tell me how to remain the resolution and crs in input_stack1 after replace -3000 as NA in output_stack1
I am not sure why you are doing what you are doing, but it suggests that you may want to look at the manual of the raster package or study the materials here
With a list of filenames create a RasterStack
library(raster)
f <- system.file("external/rlogo.grd", package="raster")
rastlist <- rep(f, 3)
s <- stack(rastlist)
(do not call stack(brick()) after that; that does not do anything useful, but could take a lot of time.)
Now reclassify the RasterStack. In this example using 255 instead of -3000.
r <- reclassify(s, cbind(255, NA))
r
#class : RasterBrick
#dimensions : 77, 101, 7777, 9 (nrow, ncol, ncell, nlayers)
#resolution : 1, 1 (x, y)
#extent : 0, 101, 0, 77 (xmin, xmax, ymin, ymax)
#crs : +proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs
#source : memory
#names : red.1, green.1, blue.1, red.2, green.2, blue.2, red.3, green.3, blue.3
#min values : 0, 0, 0, 0, 0, 0, 0, 0, 0
#max values : 254, 254, 254, 254, 254, 254, 254, 254, 254

Problem with the "stackApply" function in R

I have a problem with the "stackApply" function from the raster-package. First I want to stack three raster layers (each layer has one band) - that works. And then I want to create a raster-object that shows in which of the three bands/layers the minimum value occurs (each pixel in the raster layers has a different value). But I get various error messages. Does anyone have an idea how I can solve the problem?
Thank you
stacktest<-stack(test,test1,test2)
min_which <- stackApply(stacktest, indices=1, fun=function(x, na.rm=NULL)which.min(x))
Error in setValues(out, v) : values must be a vector
Error in is.infinite(v) : not implemented standard method for type 'list'
Here is a minimal, self-contained, reproducible example:
Example data from ?stackApply
library(raster)
r <- raster(ncol=10, nrow=10)
values(r) <- 1:ncell(r)
s <- stack(r,r,r,r,r,r)
s <- s * 1:6
Now use these data with your function (I removed the na.rm=NULL as it is not used)
w <- stackApply(s, indices=1, fun=function(x, ...) which.min(x) )
w
#class : RasterLayer
#dimensions : 10, 10, 100 (nrow, ncol, ncell)
#resolution : 36, 18 (x, y)
#extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
#crs : +proj=longlat +datum=WGS84 +no_defs
#source : memory
#names : index_1
#values : 1, 1 (min, max)
Same for which.max
w <- stackApply(s, indices=1, fun=function(x, na.rm=NULL) which.max(x) )
w
# (...)
#values : 6, 6 (min, max)
This suggest it works fine. In most cases that means that you probably have cells that are NA
s[1:10] <- NA
w <- stackApply(s, indices=1, fun=function(x, ...) which.min(x) )
# Error in setValues(out, v) : values must be numeric, logical or factor
It is easy to see why this error occurs
which.min(3:1)
#[1] 3
which.min(c(3:1, NA))
#[1] 3
which.min(c(NA, NA, NA))
#integer(0)
If all values are NA, which.min does not return NA as expected. Instead it returns an empty vector. That can be fixed like this
which.min(c(NA, NA, NA))[1]
#[1] NA
And you can do
w <- stackApply(s, indices=1, fun=function(x, ...) which.min(x)[1] )
However, using stackApply with indices=1 is not a good approach. You should generally use calc to compute cell values across all layers.
y <- calc(s, function(x) which.min(x)[1])
But in this case you can use the more straightforward
z <- which.min(s)

Shapefile: XY coordinate and Longitude/Latitude Coordinate

I have the following two shapefiles:
> summary(precincts1)
Object of class SpatialPolygonsDataFrame
Coordinates:
min max
x -74.25545 -73.70002
y 40.49613 40.91540
Precinct Shape_Leng Shape_Area
Min. : 1.00 Min. : 17083 Min. : 15286897
1st Qu.: 31.50 1st Qu.: 29900 1st Qu.: 37593804
Median : 64.50 Median : 46887 Median : 65891025
Mean : 62.57 Mean : 65720 Mean :111231564
3rd Qu.: 95.50 3rd Qu.: 76375 3rd Qu.:133644443
Max. :123.00 Max. :309518 Max. :781725787
and
> summary(bnd_nhd)
Object of class SpatialPolygonsDataFrame
Coordinates:
min max
x 871512.3 912850.5
y 982994.4 1070956.9
SHAPE_area SHAPE_len
Min. : 3173813 Min. : 7879
1st Qu.: 9687122 1st Qu.:13514
Median :14363449 Median :17044
Mean :19674314 Mean :19516
3rd Qu.:27161251 3rd Qu.:23821
Max. :68101106 Max. :49269
Their coordinate systems are different. I can overlay the shapes for "precincts1" on the map with leaflet, but I cannot do the same with for "bnd_nhd". I am using shiny, maptools, and leaflet. How can I convert the shapefile or change the setting on the map so that I can overlay the map for "bnd_nhd"?
This should work:
library("rgdal")
library("leaflet")
bnd_nhd <- readOGR("C:/data/BND_Nhd88_cw.shp",
layer="BND_Nhd88_cw")
pol_wrd <- readOGR("C:/data/POL_WRD_2010_Prec.shp",
layer="POL_WRD_2010_Prec")
bnd_nhd4326 <- spTransform(bnd_nhd, CRS("+init=epsg:4326"))
pol_wrd4326 <- spTransform(pol_wrd, CRS("+init=epsg:4326"))
m <- leaflet() %>%
addTiles() %>%
addPolygons(data=bnd_nhd4326, weight=2, color="red", group="bnd_nhd") %>%
addPolygons(data=pol_wrd4326, weight=2, color="blue", group="pol_wrd") %>%
addLayersControl(
overlayGroups = c("bnd_nhd", "pol_wrd"),
options = layersControlOptions(collapsed = FALSE)
)
m

Combine rownames from different lists in a dataframe

I have a question about lists in R. I have a list within 16 list containing a list with variables like this:
x
[[1]]
A 1 3
B 4 2
[[2]]
C 23 4
D 9 22
E 4 54
The A,B,C and D are rownames in the lists. Now I want to create a file that paste only the rownames in a dataframe. Each row in the dataframe contains 1 list in the total list.
A B
C D E
Can anyone help me with this? I thought maybe someting like do.call(rbind, rownames(x))
EDIT! 05-08-2011
Is there a way to save the rownames list by list? So in the end there are no NA's in the data and the data is unequal?
Thank you all!
Making an assumption about the nature of x, if we use:
x <- list(matrix(c(1,4,3,2), ncol = 2,
dimnames = list(c("A","B"), NULL)),
matrix(c(23,9,4,4,22,54), ncol = 2,
dimnames = list(c("C","D","E"), NULL)))
which gives:
> x
[[1]]
[,1] [,2]
A 1 3
B 4 2
[[2]]
[,1] [,2]
C 23 4
D 9 22
E 4 54
Then
> lapply(x, rownames)
[[1]]
[1] "A" "B"
[[2]]
[1] "C" "D" "E"
seems the only plausible answer. Unless we pad the ("A","B") vector with something, we can't use a matrix or a data frame because the component lengths do not match. Hence one of the reasons the do.call() idea fails:
> do.call(rbind, rownames(x))
Error in do.call(rbind, rownames(x)) : second argument must be a list
> do.call(rbind, lapply(x, rownames))
[,1] [,2] [,3]
[1,] "A" "B" "A"
[2,] "C" "D" "E"
Warning message:
In function (..., deparse.level = 1) :
number of columns of result is not a multiple of vector length (arg 1)
To pad the result with NA and get a data frame, we could do:
out <- lapply(x, rownames)
foo <- function(x, max, repl = NA) {
if(length(x) == max)
out <- x
else {
out <- rep(repl, max)
out[seq_along(x)] <- x
}
out
}
out <- lapply(out, foo, max = max(sapply(out, length)))
(out <- do.call(rbind, out))
The last line gives:
> (out <- do.call(rbind, out))
[,1] [,2] [,3]
[1,] "A" "B" NA
[2,] "C" "D" "E"
If you want that nicely printed, then
> print(format(out), quote = FALSE)
[,1] [,2] [,3]
[1,] A B NA
[2,] C D E
is an option inside R.
This should do it:
lapply(x, function(curdfr){paste(rownames(curdfr))})
This results in a vector with each element the space-separated rownames of the elements of the list.
Your sample data:
x <- list(
matrix(c(1,4,3,2), nrow = 2, dimnames = list(LETTERS[1:2])),
matrix(c(23,9,4,4,22,54), nrow = 3, dimnames = list(LETTERS[3:5]))
)
What you want:
unlist(lapply(x, rownames))
Or, if you are keen on do.call, then this is equivalent:
do.call(c, lapply(x, rownames))

R: What's the easiest way to print out pairs of values from a data.frame?

I have a data.frame:
df<-data.frame(a=c("x","x","y","y"),b=c(1,2,3,4))
> df
a b
1 x 1
2 x 2
3 y 3
4 y 4
What's the easiest way to print out each pair of values as a list of strings like this:
"x1", "x2", "y1", "y2"
apply(df, 1, paste, collapse="")
with(df, paste(a, b, sep=""))
And this should be faster than apply.
About timing
For 10000 rows we get:
df <- data.frame(
a = sample(c("x","y"), 10000, replace=TRUE),
b = sample(1L:4L, 10000, replace=TRUE)
)
N = 100
mean(replicate(N, system.time( with(df, paste(a, b, sep="")) )["elapsed"]), trim=0.05)
# 0.005778
mean(replicate(N, system.time( apply(df, 1, paste, collapse="") )["elapsed"]), trim=0.05)
# 0.09611
So increase in speed is visible for few thousands.
It's because Shane's solution call paste for each row separately. So there is nrow(df) calls of paste, in my solution is one call.
Also, you can use sqldf library:
library("sqldf")
df<-data.frame(a=c("x","x","y","y"),b=c(1,2,3,4))
result <- sqldf("SELECT a || cast(cast(b as integer) as text) as concat FROM df")
You will get the following result:
concat
1 x1
2 x2
3 y3
4 y4