Why is this r code not creating a vector? - r

I am trying to create a vector that will save the vector vprime for graphing later, but it wont't show up in my local environment (it is not writing the vector). Any ideas??
Thanks!!
###plot all three at once###
space<-seq(length=100, from=0, to=7.2) ##Create a sequence of 100 values ending at the point where value goes negative
A<- 4 #take a as given
alpha<-0.3 #take alpha as given
beta<-0.98 #take beta as given
vprime3 <- c(1:100) ##create a vector length 100 to be replaced later
t_vj3 <- c(1:100) ##create a vector length 100 to be replaced later
iterater<-function(space){ ##create a function to perform the iteration
for(i in 1:100){ ##create for loop for one of the state space (varying k+1)
for(j in 1:100){ ##create for loop for another axis of the state spcae (varying k)
if((A*(space[i]^alpha)-space[j])<0){ #plug in the law of motion
t_vj3[j]=-99 #and have a case for negative consumption so it does not take a negative log
}
else {
t_vj3[j+1] <- (log(A*(space[i]^alpha)-space[j])+ beta*t_vj3[j]) #have the law of motion for positive values
}
}
vprime3[i]<-max(t_vj3) #and create a vector of the maximum values, or the value functions
}
a4<-vprime3
plot(space,vprime3, type="p", xlab="State Space", ylab="Value") # and plot this graph
}
iterater(space) #call the function

It is creating the vector in the environment of the function body. That environment, and thus the vector goes away once the function returns.
There are two ways to get the value: Return the value and capture it, or modify the enclosing environment directly.
To return the value, change the function as follows:
iterater<-function(space){
# ....
a4<-vprime3
plot(space,vprime3, type="p", xlab="State Space", ylab="Value") # and plot this graph
# Added line
return(a4)
}
## Call iterater, saving the value:
a4 <- iterater(space)
Modifying the enclosing environment seems easy, but leads to trouble down the road, so this approach should be avoided. But to do this, change the function as follows:
iterater<-function(space){
# ....
# Note <<- instead of <-
a4<<-vprime3
plot(space,vprime3, type="p", xlab="State Space", ylab="Value") # and plot this graph
}

Related

Plotting functions of functions

So I'm kind of new to R, and I need to plot some functions. My understanding of curve in R is that it requires a function that has x as its single input. Since my functions are all just different representations of the same main function, I first thought I would create the main function, and then I would define each specific function individually.
# The principal function
puiss <- function(theta, inf, sup) {
for(k in inf:sup) {
total += (choose(30,k) * (theta^k) * ((1-theta)^(30-k)))
}
}
# The specific functions I need to draw on the same plot
p1 <- function(x) { puiss(x,2,13) }
p2 <- function(x) { puiss(x,3,14) }
p3 <- function(x) { puiss(x,3,13) }
# Can't even get to trace just a single one... :'(
curve(p1,
0, 1, # from 0 to 1
main="puissance(theta)", # title
xlab="x", ylab="theta") # axes
curve(p2, add=T) # adding the other function
curve(p3, add=T) # adding the other function
I get this error:
'expr' did not evaluate to an object of length 'n'
I've tried multiple approaches, but this one seemed to be the closest one to what it should have been.
Among other alternatives, I've tried:
changing from <- to = for the specific functions
using no {} (brackets) for the specific functions
plugging the for loop directly into the curve and replacing theta by x and inf:sup appropriately
trying to use p1(x) inside curve
I've also read that some times Vectorize() is needed, so I've tried Vectorize(p1) inside curve
What am I doing wrong?
It might help to disclose that my main function is just a Binomial(30, theta)'s mass function (probability) evaluated in different regions (the summation within the boundaries, my sigma which is a for loop because I couldn't figure out how to properly create a sigma function in R). In other words, it is a cumulative distribution function.
Ultimately, I'm trying to plot the 3 specific functions together on the same plot.
Thanks for the help! :)
It seems you are using some Python (or similar) code in your function definition.
Here is the R version of it, which for me will plot the results when calling curve.
puiss <- function(theta, inf, sup) {
total = 0
for(k in inf:sup) {
# "+=" does not work for R
total <- total + (choose(30,k) * (theta^k) * ((1-theta)^(30-k)))
}
# you need to use parentheses around total
return(total)
}

Extracting value after calculating the minimum distance between points from a spatial transect

Suppose I have a matrix in the following format derived through
https://www.mediafire.com/file/n1bds3eo7n8p34c/Bank_Farm_2_elev.tif
setwd("D:/Gs Data")
require(raster)
require(rgdal)
GDALinfo("Bank_Farm_2_elev.tif")
DEM <- raster("Bank_Farm_2_elev.tif")
test_xyz <- rasterToPoints(DEM)
colnames(test_xyz) <- c("xt", "yt", "Elev")
plot(DEM,
maxpixels=ncell(DEM),
col = grey(1:100/100),
main= "LIDAR data")
The aim is to extract a transect from the lower left corner to the upper right corner. Calculating the minimum distance between points and deriving the value for that location from the third column. Thus, creating a 1D transect of data from the 3rd column. Simple illustration:
draw_1
I have found the following code in matlab for doing this:
%Putting the measured value at each point on the transect in a variable called zt
for (j in 1:528) { % assuming nr of points for the transect. Transect
coordinates in xt and yt
myMinDist=9999999 % initialise the variable to a very large number
for (i in 1:length(text_xyz)) { % assuming the amount of points in the
whole dataset to search trhough and find the point that lies on the
transect
if ((sqrt((xt(j)-x(i))^2+(yt(j)-y(i))^2))<myMinDist){ % test to try
and get the point closes to our transect point xt(i) and yt(i)
myMinDist=sqrt((xt(j)-x(i))^2+(yt(j)-y(i))^2) % update minDist
zt(j)=(zi)
}
}
}
Which I have tried to re-write to R for the attached .tif data file
for (j in 1:528) { # the number of rows when dataset is plotted as .tif
file (given by 'dimensions' in the GDALInfo() command)
for (i in 1:length(test_xyz)) { # although length of test_xyz does not
line up with ncell?
if ((sqrt((test_xyz["xt"][j]-x[i])^2+(test_xyz["yt"][j]-y[i])^2))
<myMinDist) {
myMinDist=sqrt((test_xyz["xt"][j]-x[i])^2+(test_xyz["yt"][j]-y[i])^2)
} else {
test_xyz["Elev"][j]=(zi)
}
}
}
I think the key point that I am missing is setting up an empty vector to write my output in and a proper distinction between assigning xt and x, yt and y, zt and z within the code.
Looking forward to suggestions.
Regards.

R : how to use variables for vector indices?

I'm new user of R, and trying to generate a k-moving average graph with sine function which involves random number(in range [-0.5,+0.5]) noise.
So what I have to do is calculate a mean of consecutive (2*k+1) elements in noised-sine vector but however, the code with "HELP" below, it's not working as I expected... :(
The code seems to calculate the mean of 1 through (i-k)th element.
What's wrong with it? Help please!
set.seed(1)
x = seq(0,2*pi,pi/50)
sin_graph <- sin(x)
noise <- runif(101, -0.5, 0.5)
sin_noise <- sin_graph + noise
plot(x,sin_noise, ylim=c(-2,2))
lines(x,sin_graph, col="red")
k<-1
MA<-0
while (k<=1){
i <- k+1
MA_vector <- rep(NA, times=101)
while (i<=101-k){
MA_vector[i] <- mean(sin_noise[i-k:i+k]) #HELP!
i <- i+1
}
print(MA_vector)
plot(x, MA_vector, ylim=c(-2,2))
lines(x,sin_graph, col="red")
k<-k+1
}
As it stands, it's substracting a vector of k:i from i and then adding k. : takes precedent over mathematical operators. By using brackets (see code below), it evaluates i-k and i+k and creates a vector with min and max as results of the evaluations. I get another smooth function.
MA_vector[i] <- mean(sin_noise[(i-k):(i+k)])

How to get a SpatialPolygons (SP-class) from a set of segments (psp in spatstat)?

I have a set of random segments drawing a kind of tessellation (of triangles, rectangles ...) in a window (in spatstat R). I need to convert it into a set of polygons (SpatialPolygons) to calculate some indices (like area, shape indices ...).
This is apparently simple but I couldn't find how to do it ...
Here is a bit of code from Carl Witthoft that generate a random pattern of self-intercepting segments :
ranpoly <- function(numsegs=10,plotit=TRUE) {
require(spatstat)
# temp fix: put the first seg into segset. Later make it a constrained random.
segset<-psp(c(0,1,1,0,.25),c(0,0,1,1,0),c(1,1,0,0,1),c(0,1,1,0,.75),owin(c(0,1),c(0,1)) ) #frame the frame
for (jj in 1: numsegs) {
# randomly select a segment to start from, a point on the seg, the slope,and direction
# later... watch for slopes that immediately exit the frame
endx <-sample(c(-0.2,1.2),1) #force 'x1' outside the frame
# watch that sample() gotcha
if(segset$n<=5) sampset <- c(5,5) else sampset<-5:segset$n
startseg<-sample(sampset,1) #don't select a frame segment
# this is slope of segment to be constructed
slope <- tan(runif(1)*2*pi-pi) # range +/- Inf
# get length of selected segment
seglen<-lengths.psp(segset)[startseg]
startcut <- runif(1)
# grab the coords of starting point (similar triangles)
startx<- segset$ends$x0[startseg] + (segset$ends$x1[startseg]-segset$ends$x0[startseg])*startcut #seglen
starty<- segset$ends$y0[startseg] + (segset$ends$y1[startseg]-segset$ends$y0[startseg])*startcut #seglen
# make a psp object with that startpoint and slope; will adjust it after finding intersections
endy <- starty + slope*(endx-startx)
newpsp<-psp(startx,starty,endx,endy,segset$window,check=FALSE)
# don't calc crossing for current element of segset
hits <- crossing.psp(segset[-startseg],newpsp)
segdist <- dist(cbind(c(startx,hits$x),c(starty,hits$y)))
# dig back to get the crosspoint desired -- have to get matrixlike object out of class "dist" object
# And, as.matrix puts a zero in location 1,1 kill that row.
cutx <- hits$x[ which.min( as.matrix(segdist)[-1,1] )]
cuty <- hits$y[which.min(as.matrix(segdist)[-1,1] )]
segset <- superimpose(segset,psp(startx,starty,cutx,cuty,segset$window))
} #end jj loop
if(plotit) plot(segset,col=rainbow(numsegs))
return(invisible(segset))
}
segset=ranpoly()
segset is the psp object from wich I need to create a SpatialPolygons object.
Googling for spatstat as spatialPolygons lead me to this first hit, which is the vignette in spatstat dedicated to handeling shapefiles. It spends a lot of time on how to convert sp-classes into spatstat objects. You might be most interested in section 3.2.5: Objects of class SpatialPolygons and section 3.2.6: Objects of class SpatialPolygonsDataFrame.
Assuming that you have a set of spatstat objects, you can try something like (untested):
require(sp)
# VECTOR OF spatstat OBJECT NAMES
segs <- (seg1,seg2,seg3)
segPolys <- as(segs[1], "SpatialPolygons")
for( i in 2:length(segs)) {
y <- as(segs[i], "SpatialPolygons")
slot(y[[i]], "ID") <- paste(i)
segPolys <- c(slot(y, "polygons"),segPolys)
}

How to generate a list of segments from a list of random self-intercepting lines (psp in R)?

I'm using X=rpoisline(4) to generate lines and plot them with plot(X).
With X$ends I have their coordinates and their intersection points with selfcrossing.psp(X) (In R with spatstat : library(spatstat)).
I need to get a list of segments and their coordinates and be able to manipulate them (change their orientation, position, intersection...). Those segments have to be defined by the intersection of a line with an other line and with the window.
So, am I missing a simple way to convert a psp of few intersecting lines in a psp of non intersecting segments (I hope it's clear) ?
If you have a non-simple way, I'm interested to !
Thanks for your time !
edit :
Here are the lines I have :
And here are the kind of random stuff I think I can produce if I manage to handle each segments (one by one). So I need to get a list of segments from my list of random lines.
Ok, several coffeebreaks later, here's some buggy code that does what you want. The cleanup I'll leave to you.
ranpoly <- function(numsegs=10,plotit=TRUE) {
require(spatstat)
# temp fix: put the first seg into segset. Later make it a constrained random.
segset<-psp(c(0,1,1,0,.25),c(0,0,1,1,0),c(1,1,0,0,1),c(0,1,1,0,.75),owin(c(0,1),c(0,1)) ) #frame the frame
for (jj in 1: numsegs) {
# randomly select a segment to start from, a point on the seg, the slope,and direction
# later... watch for slopes that immediately exit the frame
endx <-sample(c(-0.2,1.2),1) #force 'x1' outside the frame
# watch that sample() gotcha
if(segset$n<=5) sampset <- c(5,5) else sampset<-5:segset$n
startseg<-sample(sampset,1) #don't select a frame segment
# this is slope of segment to be constructed
slope <- tan(runif(1)*2*pi-pi) # range +/- Inf
# get length of selected segment
seglen<-lengths.psp(segset)[startseg]
startcut <- runif(1)
# grab the coords of starting point (similar triangles)
startx<- segset$ends$x0[startseg] + (segset$ends$x1[startseg]-segset$ends$x0[startseg])*startcut #seglen
starty<- segset$ends$y0[startseg] + (segset$ends$y1[startseg]-segset$ends$y0[startseg])*startcut #seglen
# make a psp object with that startpoint and slope; will adjust it after finding intersections
endy <- starty + slope*(endx-startx)
newpsp<-psp(startx,starty,endx,endy,segset$window,check=FALSE)
# don't calc crossing for current element of segset
hits <- crossing.psp(segset[-startseg],newpsp)
segdist <- dist(cbind(c(startx,hits$x),c(starty,hits$y)))
# dig back to get the crosspoint desired -- have to get matrixlike object out of class "dist" object
# And, as.matrix puts a zero in location 1,1 kill that row.
cutx <- hits$x[ which.min( as.matrix(segdist)[-1,1] )]
cuty <- hits$y[which.min(as.matrix(segdist)[-1,1] )]
segset <- superimpose(segset,psp(startx,starty,cutx,cuty,segset$window))
} #end jj loop
if(plotit) plot(segset,col=rainbow(numsegs))
return(invisible(segset))
}
The spatstat function selfcut.psp is designed for exactly this purpose.
Y <- selfcut.psp(X)
For further information about manipulating line segment patterns, see section 4.4 in the spatstat book.

Resources