Raster to ASCII export in R- ASCII full of NA's - r

I am trying to export a raster file (.tif) as an ascii in R for subsequent analysis. The goal is to replicate this methodology (area-to-point-regression kriging), but the produced file is full of NA's. My original raster has "normal" values.
Here is a link to my ascii and tif files.
The code I have used so far:
library(raster)
#import raster
ntl = raster("mydir/ntl.tif")
#export as ascii format
writeRaster(ntl, "mydir/ntl.asc", format="ascii", overwrite = T)
I am using Windows 10, RStudio Version 1.4.1717

Your raster mostly consists of NAs, as can be illustrated like this (I prefer to use terra the replacement of raster):
library(terra)
x <- rast("ntl.tif")
plot(x, colNA="light blue")
Most of the image is light blue, that is, covered with cells that are NA
You can remove most NAs with trim
y <- trim(x)
plot(y, colNA="light blue")
You are not saying why you are creating an ascii file. I assume that you want to read the values with some other tool that does not know about spatial data file formats. In that case you might consider as.data.frame with na.rm=TRUE instead.
d <- as.data.frame(x, na.rm=TRUE, cells=TRUE)
head(d)
# cell ntl
#44592 44592 3.615484
#44593 44593 6.819953
#45010 45010 2.256919
#45011 45011 3.350195
#45012 45012 9.617457
#45013 45013 8.812189
And then save it to file, for example with
write.csv(d, "test.csv", row.names=FALSE)

Related

Crop multiple Rasters (ASCII)

I have more than 50 raster files (ASCII format) that I need to crop. I already exported the mask from ArcMap in ASCII format as well and loaded it into R. How can I make it work for all rasters in a row and export them with the same name as before (of course in a different folder to not overwrite)?
I know there is a crop function in the raster package, but I never used it so far. I only stacked them for further habitat analysis.
My Code so far:
#### Use only part of area
files2 <- list.files(path="D:/",full.names=TRUE, pattern = "\\.asc$")
files2
# Create a RasterLayer from first file
mask_raster <- raster(files2[1])
# Crop. But how??
crop(x = , y=mask_raster)
writeRaster(...)`
I did not find an easy solution to crop multiple rasters by a raster, but by a shape file. So I just went back to ArcMap and converted the raster into a shapefile. Then in R, crop and mask were the crucial steps. See code below (modified from Mauricio Zambrano-Bigiarini's code). Hope this helps.
# Reading the shapefile (mask to crop later)
Maskshp <- readOGR("mask.shp")
# Getting the spatial extent of the shapefile
e <- extent(Maskshp)
# for loop with (in this case) 60 runs
for (i in 1:60) {
# Reading the raster to crop
files <- list.files(path="...your path",full.names=TRUE, pattern = "\\.asc$")
Env_raster <- raster(files[i])
# Save the filename
filename <- (paste(basename(files[i]), sep=""))
# Crop the raster
Env_raster.crop <- crop(Env_raster, e, snap="out")
# Dummy raster with a spatial extension equal to the cropped raster,
# but full of NA values
crop <- setValues(Env_raster.crop, NA)
# Rasterize the catchment boundaries, with NA outside the catchment boundaries
Maskshp.r <- rasterize(Maskshp, crop)
# Putting NA values in all the raster cells outside the shapefile boundaries
Maskshp.masked <- mask(x=Env_raster.crop, mask=Maskshp.r)
plot(Maskshp.masked)
#Export file to working directory with original name as new name
writeRaster(Maskshp.masked, filename)
}

organising a .csv file in R

I'm programming a script for the calculation of cover around points in R.
I have two inputs: an IMG raster file, and a .csv with all the points.
I've used this script:
library(raster)
library(rgdal)
#load in raster and locality data
map <- raster('map.IMG')
sites <- read.csv('points.csv', header=TRUE)
#convert lat/lon to appropirate projection
coordinates(sites) <- c("X", "Y")
proj4string(sites) <- CRS("+init=epsg:27700")
#extract values to points
Landcover<-extract (map, sites, buffer=2000)
extraction <- lapply(Landcover, function(serial) prop.table(table(serial)))
# Write .csv file
lapply(extraction, function(x) write.table( data.frame(x), 'test2.csv' , append= T, sep=',' ))
I get a .csv file in my map, but the data isn't organised in the way I would like it to be.
There a three columns in the csv file. One with 'x', one with 'Freq' (Which I think is the code for every class in my image) and one with the cover part, somewhere between 0-1. See the image included.Image
I want to have on the rows the serial and classes, and under that the correct serial with it's coverage.
Also every point isn't named, so I can't see which is which. In the points.csv I have for example a 'serial' code for every point, which i would like to use for that.
Can somebody steer me in the right direction?
I hope I have been clear with my questions, thank in advance!

R: Crop GeoTiff Raster using packages "rgdal" and "raster"

I'd like to crop GeoTiff Raster Files using the two mentioned packages, "rgdal" and "raster". Everything works fine, except that the quality of the resulting output tif is very poor and in greyscale rather than colour. The original data are high quality raster maps from the swiss federal office of Topography, example files can be downloaded here.
This is my code:
## install.packages("rgdal")
## install.packages("raster")
library("rgdal")
library("raster")
tobecroped <- raster("C:/files/krel_1129_2012_254dpi_LZW.tif")
ex <- raster(xmn=648000, xmx=649000, ymn=224000, ymx=225000)
projection(ex) <- proj4string(tobecroped)
output <- "c:/files/output.tif"
crop(x = tobecroped, y = ex, filename = output)
In order to reproduce this example, download the sample data and extract it to the folder "c:/files/". Oddly enough, using the sample data the quality of the croped image is alright, but still greyscale.
I played around using the options "datatype", "format", but didnt get anywhere with that. Can anybody point out a solution? Should I supply more information the the input data?
EDIT:
Josh's example works superb with the sample data 2. Unfortunately, the data I have seems to be older and somewhat different. Can you tell me what option I choose if you read the following GDALinfo:
# packages same as above
OldInFile = "C:/files/krel1111.tif"
dataType(raster(OldInFile)
[1] "INT1U"
GDALinfo(OldInFile)
rows 4800
columns 7000
bands 1
lower left origin.x 672500
lower left origin.y 230000
res.x 2.5
res.y 2.5
ysign -1
oblique.x 0
oblique.y 0
driver GTiff
projection +proj=somerc +lat_0=46.95240555555556 +lon_0=7.439583333333333+k_0=1 +x_0=600000+y_0=200000 +ellps=bessel +units=m+no_defs
file C:/files/krel1111.tif
apparent band summary:
GDType hasNoDataValue NoDataValue blockSize1 blockSize2
1 Byte FALSE 0 1 7000
apparent band statistics:
Bmin Bmax Bmean Bsd
1 0 255 NA NA
Metadata:
AREA_OR_POINT=Area
TIFFTAG_RESOLUTIONUNIT=2 (pixels/inch)
TIFFTAG_XRESOLUTION=254
TIFFTAG_YRESOLUTION=254
Warning message:
statistics not supported by this driver
Edit (2015-03-10):
If one simply wants to crop out a subset of an existing GeoTIFF and save the cropped part to a new *.tif file, using gdalUtils::gdal_translate() may be the most straightforward solution:
library(raster) # For extent(), xmin(), ymax(), et al.
library(gdalUtils) # For gdal_translate()
inFile <- "C:/files/krel_1129_2012_254dpi_LZW.tif"
outFile <- "subset.tif"
ex <- extent(c(686040.1, 689715.9, 238156.3, 241774.2))
gdal_translate(inFile, outFile,
projwin=c(xmin(ex), ymax(ex), xmax(ex), ymin(ex)))
Looks like you need to change two details.
First, the *.tif file you're reading in has three bands, so should be read in using stack(). (Using raster() on it will only read in a single band (the first one, by default) producing a monochromatic or 'greyscale' output).
Second (for reasons mentioned here) writeRaster() will by default write out the values as real numbers (Float64 on my machine). To explicitly tell it you instead want to use bytes, give it the argument datatype='INT1U'.
library("rgdal")
library("raster")
inFile <- "C:/files/krel_1129_2012_254dpi_LZW.tif"
outFile <- "out.tif"
## Have a look at the format of your input file to:
## (1) Learn that it contains three bands (so should be read in as a RasterStack)
## (2) Contains values written as Bytes (so you should write output with datatype='INT1U')
GDALinfo(inFile)
## Read in as three separate layers (red, green, blue)
s <- stack(inFile)
## Crop the RasterStack to the desired extent
ex <- raster(xmn=648000, xmx=649000, ymn=224000, ymx=225000)
projection(ex) <- proj4string(s)
s2 <- crop(s, ex)
## Write it out as a GTiff, using Bytes
writeRaster(s2, outFile, format="GTiff", datatype='INT1U', overwrite=TRUE)
All of which outputs the following tiff file:

How can I save multiple jpegs from raster data in R?

I have about 40 spatial rasters in the .tiff format in a folder. I'm trying to generate histograms from each of the rasters in R, and save each histogram as a jpeg in a separate folder. I wrote code to loop through each of the raster, create a histogram and save it using the 'jpeg' package.
setwd("G:/Research/MODIS Albedo Oct 08-July 09/Test")
library(raster)
library(jpeg)
files <- list.files(path="G:/Research/MODIS Albedo Oct 08-July 09/Test", pattern=".tif",all.files=T, full.names=F, no.. = T) #generate a list of rasters in the folder
number<-length(files) #count the number of rasters
for(r in 1:number) #loop over each raster in the folder
{
x<-raster(files[r], header=F) #load one raster file
jpeg("G:/Research/MODIS Albedo Oct 08-July 09/test_histplots/r.jpg") #create jpeg using the name 'r' generated by loop
hist(x) #generate histogram
dev.off()
}
I want each of the generated jpeg to have a different name, ideally a subset of the original raster name. For example, if the original name of the raster is 'MODIS101_265', the jpeg's name should be 265. Here, 265 is the Julian date in the year. I'm assuming that this might involve using a format specifier like %d in C, but I'm not sure how this works in R.
When I run the above code, I get only one histogram. It seems the code is correctly looping over the original rasters, but saving all resultant histograms to a single jpeg.
Any advice will be helpful! Thanks!
Regular expression using gsub are your friend for getting the number out of the name. Assuming that all of your files are named the way your example is ("MODIS101_265.tif"), then the code below will work for you.
Also, welcome to R where for loops are slow and can usually be replaced by the faster lapply.
saveMyHist <- function(fileName) {
fileNum <- as.numeric(gsub(".*_(\\d+)\\.tif", "\\1", fileName))
x <- raster(fileName, header=F)
jpeg(sprintf("G:/Research/MODIS Albedo Oct 08-July 09/test_histplots/%03d.jpg",
fileNum))
hist(x)
dev.off()
}
files <- list.files("/Users/home/Documents/Development/Rtesting",
pattern=".tif",all.files=T, full.names=F, no.. = T)
lapply(files, saveMyHist)

R : How to write an XYZ file from a SpatialPointsDataFrame?

I have a SpatialPointsDataFrame which has one attribute (let's call it z for convenience) as well as lat/long coordinates.
I want to write this out to an XYZ file (i.e. an ASCII file with three columns).
Initially I tried
write.table(spdf, filename, row.names=FALSE)
but this wrote the z value first, followed by the coordinates, on each row. So it was ZXY format rather than XYZ. Not a big deal, perhaps, but annoying for other people who have to use the file.
At present I am using what feels like a really horrible bodge to do this (given below), but my question is: is there a good and straightforward way to write a SPDF out as XYZ, with the columns in the right order? It seems as though it ought to be easy!
Thanks for any advice.
Bodge:
dfOutput <- data.frame(x = coordinates(spdf)[,1], y = coordinates(spdf)[,2])
dfOutput$z <- data.frame(spdf)[,1]
write.table(dfOutput, filename, row.names=FALSE)
Why not just
library(sp)
spdf <- SpatialPointsDataFrame(coords=matrix(rnorm(30), ncol = 2),
data=data.frame(z = rnorm(15)))
write.csv(cbind(coordinates(spdf), spdf#data), file = "example.csv",
row.names = FALSE)
You can write to a .shp file using writeOGR from rgdal package. Alternatively, you could fortify (from ggplot2) your data and write that as a csv file.
Following up on Noah's comment about a method like coordinates but for data values: The raster package has the getValues() method for returning the values of a SpatialPointsDataFrame.
library(raster)
spdf <- raster('raster.sdat')
write.table(
cbind(coordinates(spdf), getValues(spdf)),
file = output_file,
col.names = c("X", "Y", "ZVALUE"),
row.names = FALSE,
quote = FALSE
)

Resources