I have a data frame which contains point daily precipitation for 4 station for 2 years. I want to interpolate to 50m resoulution and write them in to 2 raster images. I used following code to achieve this...
library(ggplot2)
library(gstat)
library(maptools)
library(raster)
library(rgdal)
xcord<-c(100,200,300,400)
ycord<-c(100,200,300,400)
value1<-c(1,2,3,1)
value2<-c(2,5,7,3)
datas<-data.frame(xcord,ycord,value1,value2)
coordinates(datas) = ~xcord+ycord
mesh <- expand.grid(x=seq(0,500,50),y=seq(0,500,50))
coordinates(mesh)=~x+y
gridded(mesh) <- TRUE
oneidw = idw(value1~1,datas,mesh)
spplot(oneidw["var1.pred"], main = " inverse distance weighted interpolations")
It worked. but i want to apply a loop to do it for another variable value2 (and so on...) without doing it manually.
and i used this
sym<-paste("value", 1:2,sep="")
variable=as.vector(print(sym,quote=FALSE))
for (i in 3:ncol(datas)){
one<-idw((print(variable[i],quote=FALSE))~1,datas,mesh)
}
but i got error too many spatial dimensions........
can anybody help me with this....
I'm not too familiar with spplot, but this worked for me using ggplot.
library(ggplot2)
library(gstat)
library(sp)
library(maptools)
library(maps)
library(dplyr)
library(rgdal)
xcord<-c(100,200,300,400)
ycord<-c(100,200,300,400)
value1<-c(1,2,3,1)
value2<-c(2,5,7,3)
datas<-data.frame(xcord,ycord,value1,value2)
new_datas <- select(datas, xcord, ycord)
parse_by <- colnames(datas)[3:4] #change according to designated value columns
for ( i in parse_by ) {
variable <- datas[i]
new_datas2 <- cbind(new_datas, variable) #combine single variable col w/ coordinates
colnames(new_datas2)[3] = "variable" #rename so that you can call to in idw formula
coordinates(new_datas2) = ~xcord+ycord
mesh <- expand.grid(x=seq(0,500,50),y=seq(0,500,50))
coordinates(mesh)=~x+y
gridded(mesh) = TRUE
plot(mesh) #plot background so ggplot can use later
points(new_datas2) #points for ggplot to use later
one<-idw(formula = variable~1, locations = new_datas2, newdata = mesh) #idw formula
one.output <- as.data.frame(one)
names(one.output)[1:3] <- c("xcord", "ycord", "var1.pred") #rename for ggplot geom_tile
ggplot() + geom_tile(data = one.output, alpha = 1, aes(x = xcord, y = ycord, fill = var1.pred)) +
geom_point(data = new_datas, aes(x = xcord, y = ycord)) +
labs(fill = "inverse distance weighted interpolations")
ggsave(paste(i,".png",sep="")) #save as .png according to variable name
}
Related
I would like to rescale the values on the legend of a plot coming from conditional_effects.
By doing something like this
plot(conditional_effects(brm_c_5, effects = "t:w_c_ratio",cond = conditions5), rug = T, points = T)
I'm getting the following
For time being I'm doing
p_col_1 <- ggplot_build(p_col_1)
and then I'm chainging the ranges in here p_col_1$plot$scales$scales[[3]]$range$range and here p_col_1$plot$scales$scales[[4]]$range$range but I'm not trusting this solution.
EXAMPLE:
As example please see this code. The defaults values for kidney$age is from 10 to 69 but let's say that I want to rescale it from -1 to 1. Then I could use the solution via ggplot_build but I'm looking for a smarter and more elegant solution.
library(brms)
fit1 <- brm(time | cens(censored) ~ age + sex + disease,
data = kidney, family = weibull, init = "0")
fit1
p_tr <- (plot(conditional_effects(fit1, effects = "disease:age"), rug = T, points = T)[[1]])
p_tr <- ggplot_build(p_tr)
p_tr$plot$scales$scales[[3]]$range$range <- c(1,0, -1) %>% as.character()
p_tr$plot$scales$scales[[4]]$range$range <- c(1, 0 ,-1)%>% as.character()
plot(p_tr %>% ggplot_gtable)
`
How could I rescale the values of w_c_ratio from -0.9:+0.9 in the original scale (which is going from 2 to 10)?
I was able to create a nice world map, I used this code for my data and I was able to obtain the point plot using the geom_point.
I want to put the data as a bar chart over the map for each country something like this image
(http://radacad.com/wp-content/uploads/2017/04/mapbarchart.png)
Could you help produce the bar chart over the map?
Here is a producible code for my data
{}
#### create the data
df <- data.frame(matrix(ncol = 8, nrow = 4))
colnames(df) <- c( "X.prj", "Y.prj","country", "Region","V1","V2","V3","V4" )
df$X.prj <- c(8649752.0,17359084.9, -744932.8, -5091132.5)
df$Y.prj <- c(5860666.76, -2263969.57,1659622.59,-4391906.10)
df$country <- c("Mongolia","Niue","Mali","Argentina")
df$Region <- c("Asia","PAC","Africa","GRULAC")
df$V1 <- c(106.4666667,258.8,56.05,1997.55)
df$V2 <- c(1.6,63.4,14.5,0)
df$V3 <- c(205.1333333, 369,169,403)
df$V4 <- c(219.3333333,175,150,247)
###############################################################################
## Create a world cities map using ggplot.
library(rgdal) # for spTransform() & project()
library(ggplot2) # for ggplot()
library(ggrepel) # for geom_text_repel() - repel overlapping text labels
library(data.table)
# =============================================================================
# Load ready to use data from GitHub
# =============================================================================
load(url("https://github.com/valentinitnelav/RandomScripts/blob/master/NaturalEarth.RData?raw=true"))
# This will load 6 objects:
# xbl.X & lbl.Y are two data.frames that contain labels for graticule lines
# They can be created with the code at this link:
# https://gist.github.com/valentinitnelav/8992f09b4c7e206d39d00e813d2bddb1
# NE_box is a SpatialPolygonsDataFrame object and represents a bounding box for Earth
# NE_countries is a SpatialPolygonsDataFrame object representing countries
# NE_graticules is a SpatialLinesDataFrame object that represents 10 dg latitude lines and 20 dg longitude lines
# (for creating graticules check also the graticule package or gridlines fun. from sp package)
# (or check this gist: https://gist.github.com/valentinitnelav/a7871128d58097e9d227f7a04e00134f)
# NE_places - SpatialPointsDataFrame with city and town points
# NOTE: data downloaded from http://www.naturalearthdata.com/
# here is a sample script how to download, unzip and read such shapefiles:
# https://gist.github.com/valentinitnelav/a415f3fbfd90f72ea06b5411fb16df16
# =============================================================================
# Project from long-lat to Eckert IV projection
# =============================================================================
# spTransform() is used for shapefiles and project() in the case of data frame
# for more PROJ.4 strings check the followings
# http://proj4.org/projections/index.html
# https://epsg.io/
# __ give the PORJ.4 string for Eckert IV projection
PROJ <- "+proj=eck4 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs"
# or use the short form "+proj=eck4"
# __ project the shapefiles
NE_countries.prj <- spTransform(NE_countries, CRSobj = PROJ)
NE_graticules.prj <- spTransform(NE_graticules, CRSobj = PROJ)
NE_box.prj <- spTransform(NE_box, CRSobj = PROJ)
# __ project long-lat coordinates columns for data frames
# (two extra columns with projected XY are created)
prj.coord <- project(cbind(lbl.Y$lon, lbl.Y$lat), proj = PROJ)
lbl.Y.prj <- cbind(prj.coord, lbl.Y)
names(lbl.Y.prj)[1:2] <- c("X.prj","Y.prj")
prj.coord <- project(cbind(lbl.X$lon, lbl.X$lat), proj = PROJ)
lbl.X.prj <- cbind(prj.coord, lbl.X)
names(lbl.X.prj)[1:2] <- c("X.prj","Y.prj")
# =============================================================================
# Prepare the data table for plotting
# =============================================================================
# melt all variable to one column
df.melt <- melt(df, id= c("X.prj","Y.prj","country","Region"),
measure.vars = 5:8)
=============================================================================
ggplot() +
# __ add layers and labels
# add projected countries
geom_polygon(data = NE_countries.prj,
aes(long,lat, group = group),
colour = "gray70", fill = "gray90", size = .25)+
# Note: "Regions defined for each Polygons" warning has to do with fortify transformation.
# fortify might get deprecated in future!
# alternatively, use use map_data(NE_countries) to transform to data frame and then use project() to change to desired projection.
# add projected bounding box
geom_polygon(data = NE_box.prj,
aes(x = long, y = lat),
colour = "black", fill = "transparent", size = .25)+
# add locations (points); add opacity with "alpha" argument&&&&&&&&&&&&&&&&&&&&&&&&&
geom_point(data = df.melt,
aes(x = X.prj, y = Y.prj, colour = Region, ),
alpha = .5)
## Here I was trying to produce the bar chart which I get a lot of error by using the code below:
for (i in 1:nrow(df)) %>% subplot(barplot(dheight=as.numeric(as.character(unlist(df[i, 5:8], use.names=F))), axes=F,
col=rainbow(4),ylim=range(df[,5:])),
x=df[i, "X.prj"], y=df[i,"Y.prj"], size=c(.6, .6))
I'm trying to enter the below data into a data frame, to make a ggplot line graph.
#functions for the hh budget and utility functions
pqxf <- function(y)(1*y) # replace p with price of y
pqyf <- function(x)(-1.25*x)+20 # -1.25 is the wage rate
utilityf <- function(x)80*(1/(x)) # 80 is the utility provided
hours <- c(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,20)
#functions are turned into data frames
pqy <- data.frame("consumption" =
pqxf(c(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,20)))
pqx <- data.frame("leisure" =
pqxf(c(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,20)))
utility <- data.frame("utility" =
utilityf(c(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,20)))
#each data frame is combined into a single data frame, that will be used for tables and charts
hh <- data.frame(pqx, pqy, utility, hours)
print(hh)
#this shows the utility, and the cost of x and y, one data frame
library(ggplot2)
ggplot(hh, aes(x=pqx, y=hours))+
xlim(0,20)+ylim(0,20)+ # limits set for the assignment
labs(x = "leisure(hours)",y="counsumption(units)")+
geom_line(aes(x = pqx, y = pqy))+
geom_line(aes(x = pqx, y = utility))+
geom_point(aes(x=8,y=10))+ #values of x and y of tangent point
geom_hline(yintercept = 10,linetype="dotted")+ # y of tangent point
geom_vline(xintercept = 8,linetype = "dotted")+ #x of tangent point
geom_text(label="E", x=8,y=10,hjust=-1,size=2)+
geom_text(label="-1.25(units/hour)= -w = MRS", x=9,y=2,hjust=.02,size=2)+
geom_text(label="U=80", x=4,y=19,hjust=1,size=2)
when I enter I get the following message:
Error in is.finite(x) : default method not implemented for type 'list'
Should I store data in a different format than a data frame? format my data frame differently, or set up ggplot differently, so that it can handle lists?
Try to replace pqx with leisure, and pqy with comsumption.
I have made a function that can plot the loadings from many factor analyses at once, also when their variables do not overlap perfectly (or at all). It works fine, but sometimes factor loadings are identical across analyses which means that the points get plotted on top of each other.
library(pacman)
p_load(devtools, psych, stringr, plotflow)
source_url("https://raw.githubusercontent.com/Deleetdk/psych2/master/psych2.R")
loadings.plot2 = function(fa.objects, fa.names=NA) {
fa.num = length(fa.objects) #number of fas
#check names are correct or set automatically
if (length(fa.names)==1 & is.na(fa.names)) {
fa.names = str_c("fa.", 1:fa.num)
}
if (length(fa.names) != fa.num) {
stop("Names vector does not match the number of factor analyses.")
}
#merge into df
d = data.frame() #to merge into
for (fa.idx in 1:fa.num) { #loop over fa objects
loads = fa.objects[[fa.idx]]$loadings
rnames = rownames(loads)
loads = as.data.frame(as.vector(loads))
rownames(loads) = rnames
colnames(loads) = fa.names[fa.idx]
d = merge.datasets(d, loads, 1)
}
#reshape to long form
d2 = reshape(d,
varying = 1:fa.num,
direction="long",
ids = rownames(d))
d2$time = as.factor(d2$time)
d2$id = as.factor(d2$id)
colnames(d2)[2] = "fa"
print(d2)
#plot
g = ggplot(reorder_by(id, ~ fa, d2), aes(x=fa, y=id, color=time, group=time)) +
geom_point(position=position_dodge()) +
xlab("Loading") + ylab("Indicator") +
scale_color_discrete(name="Analysis",
labels=fa.names)
return(g)
}
#Some example plots
fa1 = fa(iris[-5])
fa2 = fa(iris[-c(1:50),-5])
fa3 = fa(ability)
fa4 = fa(ability[1:50,])
loadings.plot2(list(fa1,fa1,fa2))
Here I've plotted the same object twice just to show the effect. The plot has no red points because the green ones from fa.2 are on top. Instead, I want them to be dodged on the y-axis. However, position="dodge" with various settings does not appear to make a difference.
However, position="jitter" works, but it is random, so sometimes it does not work well as well as makes the plot chaotic to look at.
How do I make the points dodged on the y-axis?
Apparently, you can only dodge sideways, but there is a workaround. The trick is to flip your x and y, do the position_dodge, and then do a coord_flip().
g = ggplot(data = reorder_by(id, ~ fa, d2), aes(x=id, y=fa, color=time, group=time)) +
geom_point(position=position_dodge(width = .5)) +
xlab("Loading") + ylab("Indicator") +
scale_color_discrete(name="Analysis",
labels=fa.names) +
coord_flip()
Possible duplicate
In the linked post, the right answer states that one must use position_jitter() instead of position_dodge(). It has worked for me.
So I think I have a pretty simple question, but I can't find the answer anywhere.
I have a lot of data containing catches of lobsters. It all pretty much looks like this.
Trip.ID Latitude Longitude DateTime ML6 TotalNephropsLandings
16409 OTB_CRU_32-69_0_0DK102831 57.931 9.277 2012-10-04 19:02:00 OTB_CRU_32-69_0_0 0.2188619
16410 OTB_CRU_32-69_0_0DK102831 57.959 9.375 2012-10-04 21:02:00 OTB_CRU_32-69_0_0 0.2188619
16411 OTB_CRU_32-69_0_0DK102831 58.201 10.232 2012-10-04 02:00:00 OTB_CRU_32-69_0_0 0.2188619
16412 OTB_CRU_32-69_0_0DK102831 58.208 10.260 2012-10-04 03:00:00 OTB_CRU_32-69_0_0 0.2188619
16413 OTB_CRU_32-69_0_0DK102831 58.169 10.078 2012-10-03 23:00:00 OTB_CRU_32-69_0_0 0.2188619
16414 OTB_CRU_32-69_0_0DK102831 57.919 9.227 2012-10-04 18:00:00 OTB_CRU_32-69_0_0 0.2188619
What I would like to do is simply make a map with contours around areas based on the "ML6" column, which are different tools used for fishing.
I tried using geom_density2d, which looks like this:
However I really don't want to show density, only where they are present. So basically one line around a group of coordinates that are from the same level in ML6. Could anyone help me with this?
It would also be nice to have the alternative to fill these in as polygons as well. But perhaps that could simple be accomplished using "fill=".
If anyone knows how to do this without R, you are also welcome to help, but then I would possibly need more in depth information.
Sorry for not producing more of my data frame...
Of course I should have produced the code I had for the plot, so here it is basically:
#Get map
map <- get_map(location=c(left= 0, bottom=45, right=15 ,top=70), maptype = 'satellite')
ggmap(map, extent="normal") +
geom_density2d(data = df, aes(x=Longitude, y=Latitude, group=ML6, colour=ML6))
There are probably better way of doing this work. But, here is my approach for you. I hope this approach works with ggmap as well. Given time I have, this is my best for you. Since your sample data is way too small, I decided to use a part of my own data. What you want to do is to look into ggplot_build(objectname)$data[1]. (It seems that, when you use ggmap, data would be in ggplot_build(object name)$data[4].) For example, create an object like this.
foo <- ggmap(map, extent="normal") +
geom_density2d(data = df, aes(x=Longitude, y=Latitude, group=ML6, colour=ML6))
Then, type ggplot_build(foo)$data[1]. You should see a data frame which ggplot is using. There will be a column called level. Subset data with the minimum level value. I am using filter from dplyr. For example,
foo2 <- ggplot_build(foo)$data[1]
foo3 <- filter(foo2, level == 0.02)
foo3 now has data point which allows you to draw lines on your map. This data has the data points for the most outer circles of the level. You would see something like this.
# fill level x y piece group PANEL
#1 #3287BD 0.02 168.3333 -45.22235 1 1-001 1
#2 #3287BD 0.02 168.3149 -45.09596 1 1-001 1
#3 #3287BD 0.02 168.3197 -44.95455 1 1-001 1
Then, you would do something like the following. In my case, I do not have googlemap. I have a map data of New Zealand. So I am drawing the country with the first geom_path. The second geom_path is the one you need. Make sure you change lon and lat to x and y like below.In this way I think you have the circles you want.
# Map data from gadm.org
NZmap <- readOGR(dsn=".",layer="NZL_adm2")
map.df <- fortify(NZmap)
ggplot(NULL)+
geom_path(data = map.df,aes(x = long, y = lat, group=group), colour="grey50") +
geom_path(data = foo3, aes(x = x, y = y,group = group), colour="red")
UPDATE
Here is another approach. Here I used my answer from this post. You basically identify data points to draw a circle (polygon). I have some links in the post. Please have a look. You can learn what is happening in the loop. Sorry for being short. But, I think this approach allows you to draw all circles you want. Remind that the outcome may not be nice smooth circles like contours.
library(ggmap)
library(sp)
library(rgdal)
library(data.table)
library(plyr)
library(dplyr)
### This is also from my old answer.
### Set a range
lat <- c(44.49,44.5)
lon <- c(11.33,11.36)
### Get a map
map <- get_map(location = c(lon = mean(lon), lat = mean(lat)), zoom = 14,
maptype = "satellite", source = "google")
### Create pseudo data.
foo <- data.frame(x = runif(50, 11.345, 11.357),
y= runif(50, 44.4924, 44.4978),
group = "one",
stringsAsFactors = FALSE)
foo2 <- data.frame(x = runif(50, 11.331, 11.338),
y= runif(50, 44.4924, 44.4978),
group = "two",
stringsAsFactors = FALSE)
new <- rbind(foo,foo2)
### Loop through and create data points to draw a polygon for each group.
cats <- list()
for(i in unique(new$group)){
foo <- new %>%
filter(group == i) %>%
select(x, y)
ch <- chull(foo)
coords <- foo[c(ch, ch[1]), ]
sp_poly <- SpatialPolygons(list(Polygons(list(Polygon(coords)), ID=1)))
bob <- fortify(sp_poly)
bob$area <- i
cats[[i]] <- bob
}
cathy <- as.data.frame(rbindlist(cats))
ggmap(map) +
geom_path(data = cathy, aes(x = long, y = lat, group = area), colour="red") +
scale_x_continuous(limits = c(11.33, 11.36), expand = c(0, 0)) +
scale_y_continuous(limits = c(44.49, 44.5), expand = c(0, 0))