append list for loop - r

I cannot figure out what i'm doing wrong with appending the results of a loop (as a tibble) into a list.
Below is code. I believe it has to do with the d in distance and the figures not being positive?
Error in datalist[[d]] <- dat :
attempt to select less than one element in integerOneIndex
library(tidyverse)
x <- c(10,5)
y <- c(1,3)
distance <- c(1,2,3) # distance away from the road
old<-data.frame(x,y)
datalist = list()
datalist2 = list()
for (d in 1: length(distance)) {
# Given a vector (defined by 2 points) and the distance,
# calculate a new vector that is distance away from the original
segment.shift <- function(x, y, d){
# calculate vector
v <- c(x[2] - x[1],y[2] - y[1])
# normalize vector
v <- v/sqrt((v[1]**2 + v[2]**2))
# perpendicular unit vector
vnp <- c( -v[2], v[1] )
return(list(x = c( x[1] + d*vnp[1], x[2] + d*vnp[1]),
y = c( y[1] + d*vnp[2], y[2] + d*vnp[2])))
}
# allocate memory for the bike path
xn <- numeric( (length(x) - 1) * 2 )
yn <- numeric( (length(y) - 1) * 2 )
for ( i in 1:(length(x) - 1) ) {
xs <- c(x[i], x[i+1])
ys <- c(y[i], y[i+1])
new.s <- segment.shift( xs, ys, d )
xn[(i-1)*2+1] <- new.s$x[1] ; xn[(i-1)*2+2] <- new.s$x[2]
yn[(i-1)*2+1] <- new.s$y[1] ; yn[(i-1)*2+2] <- new.s$y[2]
}
dat1<-as_tibble()
dat1<-as.data.frame(xn)%>%mutate(id=row_number())%>%mutate(Dist_Col=paste(d,"left",sep="_"))
#datalist[[d]] <- dat1 # add it to your list
dat2<-as_tibble()
dat2<-as.data.frame(yn)%>%mutate(id=row_number())%>%mutate(Dist_Col=paste(d,"left",sep="_"))
#datalist2[[d]] <- dat2 # add it to your list
###Now do right side
# allocate memory for the bike path
xn <- numeric( (length(x) - 1) * 2 )
yn <- numeric( (length(y) - 1) * 2 )
for ( i in 1:(length(x) - 1) ) {
xs <- c(x[i], x[i+1])
ys <- c(y[i], y[i+1])
new.s <- segment.shift( xs, ys, -d )
xn[(i-1)*2+1] <- new.s$x[1] ; xn[(i-1)*2+2] <- new.s$x[2]
yn[(i-1)*2+1] <- new.s$y[1] ; yn[(i-1)*2+2] <- new.s$y[2]
}
dat3<-as_tibble()
dat3<-as.data.frame(xn)%>%mutate(id=row_number())%>%mutate(Dist_Col=paste(d,"right",sep="_"))
datcomb<- full_join(dat1,dat3)
datalist[[d]] <- datcomb # add it to your list
dat4<-as_tibble()
dat4<-as.data.frame(yn)%>%mutate(id=row_number())%>%mutate(Dist_Col=paste(d,"right",sep="_"))
dat2comb<- full_join(dat2,dat4)
datalist2[[d]] <- dat2comb # add it to your list
}
big_data = do.call(rbind, datalist)
big_data2 = do.call(rbind, datalist2)
comb_data<- full_join(big_data,big_data2)
ggplot()+geom_line(data=old,aes(x,y),color='black')+geom_line(data=comb_data,aes(xn,yn,group=Dist_Col),color='red')
see updated code above which plot parallel lines on both sides of the original line.

I resolved the issue finally with
for (d in 1:length(distance))
plot update

Related

i am simulating CTMC using Gillespie Algorithm for dynamics of leprosy using 10 compartment ,encounter an error when closing my bracket after simdat,i

abcdefghij.onestep <- function (x, params) {
Susceptible <- x[2]
Exposed <- x[3]
Infected_Multibacillary <- x[4]
Infected_Paucibacillary <- x[5]
Exposed_Detected_Diagnosis <- x[6]
Treated <- x[7]
Disability <- x[8]
Recovered <- x[9]
Relapse_Multibacillary <-x[10]
Relapse_Paucibacillary <-x[11]
N <- Susceptible + Exposed + Infected_Multibacillary + Infected_Paucibacillary + Exposed_Detected_Diagnosis + Treated + Disability + Recovered + Relapse_Multibacillary + Relapse_Paucibacillary
m12 <- params["m12"]
m25 <- params["m25"]
m23 <- params["m23"]
m24 <- params["m24"]
m35 <- params["m35"]
m45 <- params["m45"]
m37 <- params["m37"]
m56 <- params["m56"]
m67 <- params["m67"]
m68 <- params["m68"]
m89 <- params["m89"]
m810 <- params["m810"]
m96 <- params["m96"]
m97 <- params["m97"]
m106 <- params["m106"]
mu <- params["mu"]
rates <- c(
birth=mu*N, susceptible_exposed=m12*Susceptible*Infected_Multibacillary -m25*Infected_Multibacillary * Exposed_Detected_Diagnosis -m23*Exposed*Infected_Multibacillary -m24*Exposed*Infected_Paucibacillary,
exposed_infected_multibacillary=m23*Exposed*Infected_Paucibacillary-m35*Infected_Multibacillary*Exposed_Detected_Diagnosis-m45* Exposed_Detected_Diagnosis* Infected_Paucibacillary-m37*Disability*Infected_Multibacillary,
exposed_infected_paucibacillary=m24*Exposed*Infected_Paucibacillary-m45*Infected_Paucibacillary*Exposed_Detected_Diagnosis,
infected_multibacillary_exposed_detected=m35*Infected_Multibacillary*Exposed_Detected_Diagnosis+m45*Infected_Paucibacillary* Exposed_Detected_Diagnosis-m56* Exposed_Detected_Diagnosis*Treated,
exposed_detected_treatment=m56*Exposed_Detected_Diagnosis*Treated-m67*Treated* Disability-m68*Treated*Recovered,
infected_multibacillary_disability=m37*Disability*Infected_Multibacillary+m67*Treated* Disability,
treated_recovered=m68* Treated*Recovered-m89*Recovered*Infected_Multibacillary-m810* Recovered*Infected_Paucibacillary,
relapse_multibacillary_treatment=-m96*Relapse_Multibacillary* Treated-m97*Relapse_Multibacillary*Disability,
relapse_paucibacillary_treatment=-m106*Relapse_Paucibacillary*Treated,
susceptible_death=mu*Susceptible,
exposed_death=mu*Exposed,
infected_multibacillary_death=mu*Infected_Multibacillary,
infected_paucibacillary_death=mu*Infected_Paucibacillary,
exposed_detected_death=mu* Exposed_Detected_Diagnosis,
treatment_death=mu*Treated,
disability_death=mu*Disability,
recovered_death=mu*Recovered,
relapse_multibacillary_death=mu*Relapse_Multibacillary,
relapse_paucibacillary_death=mu*Relapse_Paucibacilary
)
transitions <- list(
birth=c(1,0,0,0,0,0,0,0,0,0),
susceptible_exposed=c(-1,1,0,0,0,0,0,0,0,0,0,0),
exposed_infected_multibacillary=c(0,-1,1,0,0,0,0,0,0,0),
exposed_infected_paucibacillary=c(0,-1,0,1,0,0,0,0,0,0),
infected_multibacillary_exposed_detected=c(0,0,-1,0,1,0,0,0,0,0),
exposed_detected_treatment=c(0,0,0,0,-1,1,0,0,0,0),
infected_multibacillary_disability=c(0,0,-1,0,0,0,1,0,0,0),
treated_recovered=c(0,0,0,0,0,-1,0,1,0,0),
relapse_multibacillary_treatment=c(0,0,0,0,0,1,0,0,-1,0),
relapse_paucibacillary_treatment=c(0,0,0,0,0,1,0,0,0,-1),
susceptible_death=c(-1,0,0,0,0,0,0,0,0,0),
exposed_death= c(0,-1,0,0,0,0,0,0,0,0),
infected_multibacillary_death= c(0,0,-1,0,0,0,0,0,0,0),
infected_paucibacillary_death= c(0,0,0,-1,0,0,0,0,0,0),
exposed_detected_death= c(0,0,0,0,-1,0,0,0,0,0),
treatment_death= c(0,0,0,0,0,-1,0,0,0,0),
disability_death= c(0,0,0,0,0,0,-1,0,0,0),
recovered_death= c(0,0,0,0,0,0,0,-1,0,0),
relapse_multibacillary_death= c(0,0,0,0,0,0,0,0,-1,0),
relapse_paucibacillary_death= c(0,0,0,0,0,0,0,0,0,-1)
)
total.rate <- sum(rates)
if (total.rate==0)
tau <- Inf
else
tau <- rexp(n=1,rate=total.rate)
event <- sample.int(n=6,size=1,prob=rates/total.rate)
x+c(tau,transitions[[event]])
}
abcdefghij.simul <- function (x, params, maxstep = 10000) {
output <- array(dim=c(maxstep+1,4))
colnames(output) <- names(x)
output[1,] <-x
k <- 1
while ((k <= maxstep) && (x["Exposed"] > 0)) {
k <- k+1
output[k,] <- x <- abcdefghij.onestep(x,params)
}
as.data.frame(output[1:k,])
}
And in R this happens:
> set.seed(56856583)
> nsims <- 1
> xstart <- c(time=1,Susceptible=100000,Exposed=1,Infected_Multibacillary=1,Infected_Paucibacillary=1,Exposed_Detected_Diagnosis=1,Treated=1,Disability=1,Recovered=1,Relapse_Multibacillary=1,Relapse_Paucibacillary=1)
> library(plyr)
> simdat <- rdply(nsims, abcdefghij.simul(xstart,params))
Error in dimnames(x) <- dn :
length of 'dimnames' [2] not equal to array extent
Called from: `colnames<-`(`*tmp*`, value = names(x))
Browse[1]>
Change this line:
output <- array(dim=c(maxstep+1,4))
To this instead:
output <- array(dim=c(maxstep+1,11))
Your xstart variable has 11 elements. If you want them all on one row, you have to create something that is 11 columns wide, not 4. Perhaps you had just 4 values in the beginning.
Furthermore you don't seem to define params anywhere. The code won't run until you do.

How can I run my Newton's method in this case?

There is a function like:
y = (e^x - 2)^n
The x is an unknown, for n = 2,3,4,...,8
Now I want to use NR method to find the root of this function(initial x is 0).
I know how to write an NR method if the n is a fixed value, here's my origin NR code:
NR <- function(f, x0, tol = 1e-5, ite = 1000){
require(numDeriv) #call the package for computing dx
k <- ite
for (i in 1:ite){
#calculate dx
dx <- genD(func = f, x = x0)$D[1]
#get the x1
x1 <- x0 - (f(x0) / dx)
k[i] <- x1
if(abs(x1 - x0) < tol){
root <- x1
re <- list('root approximation' = root, 'iteration' = length(k))
return(re)
}
x0 <- x1
}
print('Outside the upper iteration')
}
Now I rewrite my function:
f <- function(x, n){
(exp(x) - 2) ^ n
}
If I want to output every root for different n, I think I should add another loop before the loop "for (i in 1:ite)"
So I rewrite my NR function code:
NR <- function(f, x0, tol = 1e-5, ite = 1000){
require(numDeriv) #call the package for computing dx
k <- ite
for(n in 2:8){
for (i in 1:ite){
#calculate dx
dx <- genD(func = f, x = x0)$D[1]
#get the x1
x1 <- x0 - (f(x0, n) / dx)
k[i] <- x1
if(abs(x1 - x0) < tol){
root <- x1
re <- list('root approximation' = root, 'iteration' = length(k))
return(re)
}
x0 <- x1
}
print('Outside the upper iteration')
}
}
But when I run NR(f,0), R showed me the error is :
Error in func(x, ...) : argument "n" is missing, with no default
How can I figure this out?
Thank you for your help!
I hope you find my answer helpful:
If you try ?genD you will read this:
Usage
genD(func, x, method="Richardson",
method.args=list(), ...)
## Default S3 method: genD(func, x, method="Richardson",
method.args=list(), ...) Arguments
func a function for which the first (vector) argument is used as a
parameter vector. x The parameter vector first argument to func.
And in the bottom of the R Documentation this example:
Examples
func <- function(x){c(x[1], x[1], x[2]^2)}
z <- genD(func, c(2,2,5))
Therefore, the issue with your code is that you need to use a vector as an argument for f:
f <- function(c){ (exp(c[1]) - 2) ^ c[2] }
NR <- function(f, x0, tol = 1e-5, ite = 1000){ require(numDeriv)
#call the package for computing dx k <- ite for(n in 2:8){
for (i in 1:ite){
#calculate dx
dx <- genD(func = f, x = c(x0,n))$D[1]
#get the x1
x1 <- x0 - (f(c(x0,n)) / dx)
k[i] <- x1
if(abs(x1 - x0) < tol){
root <- x1
re <- list('root approximation' = root, 'iteration' = length(k))
return(re)
}
x0 <- x1
}
print('Outside the upper iteration') } }
NR(f,0)
If I run that my output is:
$`root approximation` [1] 0.6931375
$iteration [1] 15
Best!

Error in seq.default(a, length = max(0, b - a - 1)) : length must be non-negative number

I tried running the code below.
set.seed(307)
y<- rnorm(200)
h2=0.3773427
t=seq(-3.317670, 2.963407, length.out=500)
fit=density(y, bw=h2, n=1024, kernel="epanechnikov")
integrate.xy(fit$x, fit$y, min(fit$x), t[407])
However, i recived the following message:
"Error in seq.default(a, length = max(0, b - a - 1)) :
length must be non-negative number"
I am not sure what's wrong.
I do not encounter any problem when i use t[406] or t[408] as follow:
integrate.xy(fit$x, fit$y, min(fit$x), t[406])
integrate.xy(fit$x, fit$y, min(fit$x), t[408])
Does anyone know what's the problem and how to fix it? Appreciate your help please. Thanks!
I went through the source code for the integrate.xy function, and there seems to be a bug relating to the usage of the xtol argument.
For reference, here is the source code of integrate.xy function:
function (x, fx, a, b, use.spline = TRUE, xtol = 2e-08)
{
dig <- round(-log10(xtol))
f.match <- function(x, table) match(signif(x, dig), signif(table,
dig))
if (is.list(x)) {
fx <- x$y
x <- x$x
if (length(x) == 0)
stop("list 'x' has no valid $x component")
}
if ((n <- length(x)) != length(fx))
stop("'fx' must have same length as 'x'")
if (is.unsorted(x)) {
i <- sort.list(x)
x <- x[i]
fx <- fx[i]
}
if (any(i <- duplicated(x))) {
n <- length(x <- x[!i])
fx <- fx[!i]
}
if (any(diff(x) == 0))
stop("bug in 'duplicated()' killed me: have still multiple x[]!")
if (missing(a))
a <- x[1]
else if (any(a < x[1]))
stop("'a' must NOT be smaller than min(x)")
if (missing(b))
b <- x[n]
else if (any(b > x[n]))
stop("'b' must NOT be larger than max(x)")
if (length(a) != 1 && length(b) != 1 && length(a) != length(b))
stop("'a' and 'b' must have length 1 or same length !")
else {
k <- max(length(a), length(b))
if (any(b < a))
stop("'b' must be elementwise >= 'a'")
}
if (use.spline) {
xy <- spline(x, fx, n = max(1024, 3 * n))
if (xy$x[length(xy$x)] < x[n]) {
if (TRUE)
cat("working around spline(.) BUG --- hmm, really?\n\n")
xy$x <- c(xy$x, x[n])
xy$y <- c(xy$y, fx[n])
}
x <- xy$x
fx <- xy$y
n <- length(x)
}
ab <- unique(c(a, b))
xtol <- xtol * max(b - a)
BB <- abs(outer(x, ab, "-")) < xtol
if (any(j <- 0 == apply(BB, 2, sum))) {
y <- approx(x, fx, xout = ab[j])$y
x <- c(ab[j], x)
i <- sort.list(x)
x <- x[i]
fx <- c(y, fx)[i]
n <- length(x)
}
ai <- rep(f.match(a, x), length = k)
bi <- rep(f.match(b, x), length = k)
dfx <- fx[-c(1, n)] * diff(x, lag = 2)
r <- numeric(k)
for (i in 1:k) {
a <- ai[i]
b <- bi[i]
r[i] <- (x[a + 1] - x[a]) * fx[a] + (x[b] - x[b - 1]) *
fx[b] + sum(dfx[seq(a, length = max(0, b - a - 1))])
}
r/2
}
The value given to the xtol argument, is being overwritten in the line xtol <- xtol * max(b - a). But the value of the dig variable is calculated based on the original value of xtol, as given in the input to the function. Because of this mismatch, f.match function, in the line bi <- rep(f.match(b, x), length = k), returns no matches between x and b (i.e., NA). This results in the error that you have encountered.
A simple fix, at least for the case in question, would be to remove the xtol <- xtol * max(b - a) line. But, you should file a bug report with the maintainer of this package, for a more rigorous fix.

Can't Convert `for` Loop to `apply` Function

I've converted for loops I've found in the past into apply functions e.g.:
y <- 6:10
z <- 1:5
for(i in 1:length(y)){
z[i] <- y[i] * y[i]^2
}
z
z <- sapply(X = 1:length(y), FUN = function(i){
y[i] * y[i]^2
})
z
But the following loop has been giving me issues today:
lambda <- 2.9
n <- 20
z <- 1:n
x <- 0.02
z[1] <- x
for(i in 1:(n - 1)){
z[i + 1] <- lambda * z[i] * (1 - z[i])
}
z
z <- 1:n
z[1] <- x
sapply(X = 1:(n - 1), FUN = function(i){
lambda * z[i] * (1 - z[i])
})
Does anyone see the bug?
Because you need result from previous step (eg. z[i+1]=f(z[i] ), you can not use sapply which results are available at the end of all steps.
For this you can use accumulate from package purrr:
purrr::accumulate(1:(n-1), ~(lambda * . * (1 - .)), .init=x)
[1] 0.0200000 0.0568400 0.1554667 0.3807608 0.6837678 0.6270652 0.6781778 0.6329327
[9] 0.6737538 0.6374479 0.6702134 0.6409794 0.6673619 0.6437710 0.6650567 0.6459932
[17] 0.6631894 0.6477708 0.6616750 0.6491974
where ~ defines a function taking 2 parameters (. and .y), . being reinjected from previous step and .y is the next step value
To better understand try:
purrr::accumulate(1:n, ~.)
purrr::accumulate(1:n, ~.y)

How to convert UK grid reference to latitude and longitude in R

I have a vector of UK British National Grid references:
x <- c("SK393744", "SK442746", "SK376747", "SK108191", "SP169914", "SP206935", "SK173105", "SJ993230", "SK448299", "SK112396")
I need to convert this vector in WGS84 coordinates (latitude and longitude).
How can I do it using R?
Give these a go. If they work, I'll make a package with a few more of the other functions in that javascript library (which also has sister PHP & Java libraries, so it's fitting R shld have one).
# takes numeric east/north generated from the os.grid.parse() function
# i shld have made it take the vector the os.grid.parse() returns but
# we'll save that for a proper package version
os.grid.to.lat.lon <- function(E, N) {
a <- 6377563.396
b <- 6356256.909
F0 <- 0.9996012717
lat0 <- 49*pi/180
lon0 <- -2*pi/180
N0 <- -100000
E0 <- 400000
e2 <- 1 - (b^2)/(a^2)
n <- (a-b)/(a+b)
n2 <- n^2
n3 <- n^3
lat <- lat0
M <- 0
repeat {
lat <- (N-N0-M)/(a*F0) + lat
Ma <- (1 + n + (5/4)*n2 + (5/4)*n3) * (lat-lat0)
Mb <- (3*n + 3*n*n + (21/8)*n3) * sin(lat-lat0) * cos(lat+lat0)
Mc <- ((15/8)*n2 + (15/8)*n3) * sin(2*(lat-lat0)) * cos(2*(lat+lat0))
Md <- (35/24)*n3 * sin(3*(lat-lat0)) * cos(3*(lat+lat0))
M <- b * F0 * (Ma - Mb + Mc - Md)
if (N-N0-M < 0.00001) { break }
}
cosLat <- cos(lat)
sinLat <- sin(lat)
nu <- a*F0/sqrt(1-e2*sinLat*sinLat)
rho <- a*F0*(1-e2)/((1-e2*sinLat*sinLat)^1.5)
eta2 <- nu/rho-1
tanLat <- tan(lat)
tan2lat <- tanLat*tanLat
tan4lat <- tan2lat*tan2lat
tan6lat <- tan4lat*tan2lat
secLat <- 1/cosLat
nu3 <- nu*nu*nu
nu5 <- nu3*nu*nu
nu7 <- nu5*nu*nu
VII <- tanLat/(2*rho*nu)
VIII <- tanLat/(24*rho*nu3)*(5+3*tan2lat+eta2-9*tan2lat*eta2)
IX <- tanLat/(720*rho*nu5)*(61+90*tan2lat+45*tan4lat)
X <- secLat/nu
XI <- secLat/(6*nu3)*(nu/rho+2*tan2lat)
XII <- secLat/(120*nu5)*(5+28*tan2lat+24*tan4lat)
XIIA <- secLat/(5040*nu7)*(61+662*tan2lat+1320*tan4lat+720*tan6lat)
dE <- (E-E0)
dE2 <- dE*dE
dE3 <- dE2*dE
dE4 <- dE2*dE2
dE5 <- dE3*dE2
dE6 <- dE4*dE2
dE7 <- dE5*dE2
lon <- lon0 + X*dE - XI*dE3 + XII*dE5 - XIIA*dE7
lat <- lat - VII*dE2 + VIII*dE4 - IX*dE6
lat <- lat * 180/pi
lon <- lon * 180/pi
return(c(lat, lon))
}
# takes a string OS reference and returns an E/N vector
os.grid.parse <- function(grid.ref) {
grid.ref <- toupper(grid.ref)
# get numeric values of letter references, mapping A->0, B->1, C->2, etc:
l1 <- as.numeric(charToRaw(substr(grid.ref,1,1))) - 65
l2 <- as.numeric(charToRaw(substr(grid.ref,2,2))) - 65
# shuffle down letters after 'I' since 'I' is not used in grid:
if (l1 > 7) l1 <- l1 - 1
if (l2 > 7) l2 <- l2 - 1
# convert grid letters into 100km-square indexes from false origin - grid square SV
e <- ((l1-2) %% 5) * 5 + (l2 %% 5)
n <- (19 - floor(l1/5) *5 ) - floor(l2/5)
if (e<0 || e>6 || n<0 || n>12) { return(c(NA,NA)) }
# skip grid letters to get numeric part of ref, stripping any spaces:
ref.num <- gsub(" ", "", substr(grid.ref, 3, nchar(grid.ref)))
ref.mid <- floor(nchar(ref.num) / 2)
ref.len <- nchar(ref.num)
if (ref.len >= 10) { return(c(NA,NA)) }
e <- paste(e, substr(ref.num, 0, ref.mid), sep="", collapse="")
n <- paste(n, substr(ref.num, ref.mid+1, ref.len), sep="", collapse="")
nrep <- 5 - match(ref.len, c(0,2,4,6,8))
e <- as.numeric(paste(e, "5", rep("0", nrep), sep="", collapse=""))
n <- as.numeric(paste(n, "5", rep("0", nrep), sep="", collapse=""))
return(c(e,n))
}

Resources