Here is a silly (maybe only in my mind) way to accomplish my goal:
A <- "This is a test."
B <- "This is the answer."
swap <- function(item1,item2) {
tmp <- item2
item2 <- item1
item1 <- tmp
return(list(item1,item2))
}
AB <- swap(A,B)
A <- AB[[1]]
B <- AB[[2]]
But I'm considering something similar to the C code following:
void swap(int *a, int *b)
{
int iTemp ;
iTemp = *a;
*a = *b;
*b = iTemp;
}
My motivations:
My real data is quite large, e.g. 5k*5k matrix, so the assignment of the existing variable in the iteration twice, inside the function and outside the function, must be time squandering.
The closest question on the SO is this one, but just like the OP in the question, my R session also has lots of objects: I'm working with Rmpi, and each slave will have a great number of variables.
In my humble opinion, R is written in C, so R may have pointers like C does, while I can't find much on the net surprisingly.
How about this; this just assigns to the parent environment.
A <- "This is a test."
B <- "This is the answer."
swap <- function(item1, item2) {
tmp <- item1
assign(deparse(substitute(item1)), item2, pos = 1)
assign(deparse(substitute(item2)), tmp, pos = 1)
}
swap(A, B)
A
#[1] "This is the answer."
B
#[1] "This is a test.
Related
I am trying to create an SEIR model with multiple patches using the package deSolve in R. At each time step, there is some movement of individuals between patches that can infect individuals in other patches. I also have an external forcing parameter that is specific to each patch (representing different environmental conditions). I've been able to get this working in base R, but given the number of patches and compartments and the duration of the model, I'm trying to convert it to compiled code to speed it up.
I've gotten the different patches working, but am struggling with how to incorporate a different forcing parameter for each patch. When forcings are provided, there is an automatic check checkforcings (https://rdrr.io/cran/deSolve/src/R/forcings.R) that doesn't allow for a matrix with more than two columns, and I'm not quite sure what the best workaround is for this. Write my own ode and checkforcings functions to override this? Restructure the forcings data once it gets into C? My final model has 195 patches so I'd prefer to be to automate it somehow so I am not writing out thousands of equations or hundreds of functions.
Also fine if the answer is just, do this in a different language, but would appreciate insight into what language I should switch to. Julia maybe?
Below is code for a very simple example that just highlights this "different forcings in different patches problem".
R Code
# Packages #########################################################
library(deSolve)
library(ggplot2); theme_set(theme_bw())
library(tidyr)
library(dplyr)
# Initial Parameters and things ####################################
times <- 1:500
n_patch <- 2
patch_ind <- 100
state_names <- (c("S", "I"))
n_state <- length(state_names)
x <-rep(0, n_patch*n_state)
names(x) <- unlist(lapply(state_names, function(x) paste(x,
stringr::str_pad(seq(n_patch), width = 3, side = "left", pad =0),
sep = "_")))
#start with infected individuals in patch 1
x[startsWith(names(x), "S")] <- patch_ind
x['S_001'] <- x['S_001'] - 5
x['I_001'] <- x['I_001'] + 5
x['I_002'] <- x['I_002'] + 20
params <- c(gamma = 0.1, betam = 0.2)
#seasonality
forcing <- data.frame(times = times,
rain = rep(rep(c(0.95,1.05), each = 50), 5))
new_approx_fun <- function(rain.column, t){
approx_col <- approxfun(rain.column, rule = 2)
return(approx_col(t))
}
rainfall2 <- data.frame(P1 = forcing$rain,
P2 = forcing$rain+0.01)
# model in R
r.mod2 <- function(t,x,params){
# turn state.vec into matrix
# columns are different states, rows are different patches
states <- matrix(x,
nrow = n_patch,
ncol = n_state, byrow = F)
S <- states[,1]
I <- states[,2]
N <- rowSums(states[,1:2])
with(as.list(params),{
#seasonal forcing
rain <- as.numeric(apply(as.matrix(rainfall2), MARGIN = 2, FUN = new_approx_fun, t = t))
dS <- gamma*I - rain*betam*S*I/N
dI <- rain*betam*S*I/N - gamma*I
return(list(c(dS, dI), rain))
})
}
out.R2 <- data.frame(ode(y = x, times =times, func = r.mod2,
parms = params))
#create seasonality for C
ftime <- seq(0, max(times), by = 0.1)
rain.ft <- approx(times, rainfall2$P1, xout = ftime, rule = 2)$y
forcings2 <- cbind(ftime, rain.ft, rain.ft +0.01)
# C model
system("R CMD SHLIB ex-patch-season-multi.c")
dyn.load(paste("ex-patch-season-multi", .Platform$dynlib.ext, sep = ""))
out.dll <- data.frame(ode(y = x, times = times, func = "derivsc",
dllname = "ex-patch-season-multi", initfunc = "parmsc",
parms = params, forcings = forcings2,
initforc = "forcc", nout = 1, outnames = "rain"))
C code
#include <R.h>
#include <math.h>
#include <Rmath.h>
// this is for testing to try and get different forcing for each patch //
/*define parameters, pay attention to order */
static double parms[2];
static double forc[1];
#define gamma parms[0]
#define betam parms[1]
//define forcing
#define rain forc[0]
/* initialize parameters */
void parmsc(void (* odeparms)(int *, double *)){
int N=2;
odeparms(&N, parms);
}
/* forcing */
void forcc(void (* odeforcs)(int *, double *))
{
int N=1;
odeforcs(&N, forc);
}
/* model function */
void derivsc(int *neq, double *t, double *y, double *ydot, double *yout, int *ip){
//use for-loops for patches
//define all variables at start of block
int npatch=2;
double S[npatch]; double I[npatch]; double N[npatch];
int i;
for(i=0; i<npatch; i++){
S[i] = y[i];
};
for(i=0; i <npatch; i++){
int ind = npatch+i;
I[i] = y[ind];
};
for(i=0; i<npatch; i++){
N[i] = S[i] + I[i];
};
//use for loops for equations
{
// Susceptible
for(i=0; i<npatch; i++){
ydot[i] = gamma*I[i] - rain*betam*I[i]*S[i]/N[i] ;
};
//infected
for(i=0; i<npatch; i++){
int ind=npatch+i;
ydot[ind] = rain*betam*I[i]*S[i]/N[i] - gamma*I[i];
};
};
yout[0] = rain;
}
The standard way for multiple forcings in compiled code of the deSolve package is described in the lsoda help page:
forcings only used if ‘dllname’ is specified: a list with the forcing function data sets, each present as a two-columned matrix
Such a list can be created automatically in a script.
There are also other ways possible with some creative C or Fortran programming.
For more complex models, I would recommend to use the rodeo package. It allows to specify dynamic models in a tabular form (CSV, LibreOffice, Excel), including parameters and forcing functions. The code generator of the package creates then a fast Fortran code, that can be solved with deSolve. An overview can be found in a paper of Kneis et al (2017), https://doi.org/10.1016/j.envsoft.2017.06.036 and a more extended tutorial at https://dkneis.github.io/ .
I´m trying to write a function in which I´m creating vectors such as a, b, c. I wrote several conditional statements to create these vectors and some of them might not exist at the end of the function. I´m struggling to write the return of the function; I would like to return them as lists:
return(list(a, b, c))
but I need to find a way to re-write it in a way that for example, if b doesn't exist, a and c will be returned and perhaps I can add a message of "doesn't exist" for b.
Can you please help me in finding an easy solution? Thanks!
Not the most elegant, but this could do it.
If you need to check for the existence of a lot of objects, then it is better to write what I wrote in the if else in a functional form.
func <- function() {
a <- 1 # so a exists
ret_list <- list()
if (exists("a", inherits = FALSE)) {
ret_list <- c(ret_list, a = a)
} else {
ret_list <- c(ret_list, a = "a doesn't exist")
}
if (exists("b", inherits = FALSE)) {
ret_list <- c(ret_list, b = b)
} else {
ret_list <- c(ret_list, b = "b doesn't exist")
}
ret_list
}
Output
ret <- func()
ret
#$a
#[1] 1
#
#$b
#[1] "b doesn't exist"
Edited the above code to include inherits = FALSE in the exists function. If not exists("c") would return TRUE even when there isn't an object "c" as it would think "c" refer to the (base R) function c().
Why is:
c(d = 1:3)
equal to a named vector, as:
d1 d2 d3
1 2 3
And where is this behavior documented?
The c help file does say:
## do *not* use
c(ll, d = 1:3) # which is == c(ll, as.list(c(d = 1:3))
but the as.list is superfluous (and the closing parenthesis missing). And I don't think that amounts to documentation of the behavior above.
That's a nice observation which took me to the actual C Code (since c() is a Primitive function). Just sharing my observation from the code.
And in the actual C code do_c() function that does this c() for R and inside that function there's a section dedicated to assign attributes to the output.
/* Build and attach the names attribute for the returned object. */
if (data.ans_nnames && data.ans_length > 0) {
PROTECT(data.ans_names = allocVector(STRSXP, data.ans_length));
data.ans_nnames = 0;
while (args != R_NilValue) {
struct NameData nameData;
nameData.seqno = 0;
nameData.count = 0;
NewExtractNames(CAR(args), R_NilValue, TAG(args), recurse, &data, &nameData);
args = CDR(args);
}
setAttrib(ans, R_NamesSymbol, data.ans_names);
UNPROTECT(1);
}
which tells us NewExtractNames() is the function that specifically create names and exploring that we can find the information that the sequence is created
/* NewExtractNames(v, base, tag, recurse): For c() and unlist().
* On entry, "base" is the naming component we have acquired by
* recursing down from above.
* If we have a list and we are recursing, we append a new tag component
* to the base tag (either by using the list tags, or their offsets),
* and then we do the recursion.
* If we have a vector, we just create the tags for each element. */
So, to your question it doesn't seem to have been documented anywhere that attribute names are generated with a sequence and assigned it to the result.
Hope it helps.
You can modify this behaviour changing use.names parameter:
c(d = 1:3)
d1 d2 d3
1 2 3
c(d = 1:3,use.names=F)
[1] 1 2 3
More details here:
https://www.rdocumentation.org/packages/base/versions/3.4.3/topics/c
Learning Nim and I like it resemblence of Python (but fast). In Python I can do this:
item_index = [(idx, itm) for idx, itm in enumerate(row)]
Im looking for a way to enumerate a Nim sequence so I would write this:
item_index = lc[(idx, itm) | (idx, itm <- enumerate(row))]
Does this functionality exist? I'm sure you could create it, maybe with a proc, template or macro it but I'm still very new, and these seem hard to create myself still. Here is my attempt:
iterator enumerate[T](s: seq[T]): (int, T) =
var i = 0
while i < len(s):
yield (i, s[i])
i += 1
I'm a newbie with nim, and I'm not really sure what you want, but...
If you use two variables in a for statement, you will get the index and the value:
for x, y in [11,22,33]:
echo x, " ", y
Gives:
0 11
1 22
2 33
HTH.
My custom iterator is a bit slow. I hope to get a speed up when I use the unlist(as.list(ic, n=2000)) construct. However, I do not know how to implement this functionality. I only found the nextElem and hasNext methods. The iterator looks like this:
library(itertools)
fibonacci <- function(count = NA) {
ab = c(0, 1)
n <- function() {
if (!is.na(count)) {
if (count > 0) count <<- count -1
else stop('StopIteration')
}
#
ab <<- c(ab[2], sum(ab))
ab[1]
}
obj <- list(nextElem = n)
class(obj) <- c('fibonacci', 'abstractiter', 'iter')
obj
}
I can use it like this:
ic <- fibonacci ()
print (nextElem (ic))
Now I would like to get the next 10 fibonacci numbers at once, via
print(unlist(as.list(ic, n=10)))
But this of course needs to be implemented. How would I do this?
The fibonacci iterator serves as an example. Actually, I work on an iterator that gives all k-combinations of an n-set, i.e. a memory-friendly version of combn.