Function with variables that are different dataframe sizes - r

So I´m trying to run the fuction below hoping to get 224 vectors in the output, but only get one and I have no idea why.
ee <- 0.95
td <- 480
tt <- c(60,10,14,143,60)
tt <- as.data.frame(tt)
r <- vector()
m <- function(d)
{
n <- length(tt)
c <- nrow(d)
for (j in 1:c)
{
for (i in 1:n)
{
r[i] <- tt[i]/(td*ee/d[j,])
}
return(r)
}
#where d is a data frame of 224 obs. of 1 variable
and the output i´m getting is
[[1]]
[1] 1026.3158 171.0526 239.4737 2446.0526 1026.3158

The problem comes from the fact that your function returns only the last r vector that is computed, due to where return is placed within your loop.
One way to do this is to store the results in a list:
r <- vector()
m_bis <- function(d) {
res <- list() # store all the vectors here
n <- length(tt)
c <- nrow(d)
for (j in 1:c) {
for (i in 1:n) {
r[i] <- tt[i] / (td * ee / d[j,])
}
res[j] <- r
}
return(res)
}
That should yield something like this:
m_bis(as.data.frame(mtcars$mpg))
> [[1]]
[1] 2.7631579 0.4605263 0.6447368 6.5855263 2.7631579
...
[[32]]
[1] 2.8157895 0.4692982 0.6570175 6.7109649 2.8157895

outer(as.vector(tt[,1]), as.vector(d[,1]), function(x,y){x*y/(td*ee)})
Use vectorization to accelerate the computation.

Related

R: function to create a list of subset/smaller dataframes from a existing larger dataframe according to date

I am starting with a large dataframe. I would like to divide this into smaller dataframes. I have created a function to do this in a loop
This is function code in R
getPortfolios <- function(n) {
i = 1
listofdfs <- list()
for (i in 1:n) {
df <- data.frame(subset(df_log_returns, mdy(row.names(df_log_returns)) >= var$var[i] & mdy(row.names(df_log_returns)) <= var$var[i]))
listofdfs[[i]] <- list(df)
}
return(listofdfs)
}
when I run getPortfolio(1) and call listofdfs[1] I get the error Error: object 'listofdfs' not found
This is particularly puzzling bc when I run this as a simple loop:
listofdfs <- list()
n <- 16
for (i in 1:n) {
df <- data.frame(subset(df_log_returns, mdy(row.names(df_log_returns)) >= var$var[i] & mdy(row.names(df_log_returns)) <= var$var[i]))
listofdfs[[i]] <- df
}
listofdfs can be called...hmmmmm so puzzling...
You should use
listofdfs <- getPortfolio(*)`
instead of
getPortfolio(*)

Function: save returned data frame to workspace

I cannot really get my head around this problem:
I have a function that returns a data frame. However, the data frame is only printed in my console although I would like to have it stored in the work space. How can I achieve this?
Sample data:
n <- 32640
t <- seq(3*pi,n)
data_sim <- 30+ 2*sin(3*t)+rnorm(n)*10
data_sim <- floor(data_sim)
Function:
compress <- function (name, SR){
## -------------------------------------------------------
## COMPRESSION
library(zoo)
data <- get(name)
if (is.data.frame(data)==F){
data = as.data.frame(data)
}
SR <- SR
acrossmin <- 60
a <- nrow(data)
m <- acrossmin*SR*60
data_compress <- matrix(NA, nrow = a/m)
no_mov_subset <- matrix(NA, nrow = m)
for (i in 1:(a/m)){
subset <- data[(((i-1)*m)+1):((i*m)),]
b <- length(subset)
for (k in 1:b){
r <- subset[k]
if (r == 0){
no_mov_subset[k] <- 0
} else {
no_mov_subset[k] <- 1
}
sum_no_mov_subset <- sum(no_mov_subset)
data_compress[i] <- sum_no_mov_subset
}
colnames(data_compress) <- c("activity_count")
return(data_compress)
}
Run the code:
compress("data_sim", 4/60)
Obviously, the function returns something, but I would like it to be stored in the workspace rather than returned!
Instead of the return command you can use
data_compress <<- data_compress
This way, the data frame is stored in the workspace. So your function looks like this:
compress <- function (name, SR){
## -------------------------------------------------------
## COMPRESSION
library(zoo)
data <- get(name)
if (is.data.frame(data)==F){
data = as.data.frame(data)
}
SR <- SR
acrossmin <- 60
a <- nrow(data)
m <- acrossmin*SR*60
data_compress <- matrix(NA, nrow = a/m)
no_mov_subset <- matrix(NA, nrow = m)
for (i in 1:(a/m)){
subset <- data[(((i-1)*m)+1):((i*m)),]
b <- length(subset)
for (k in 1:b){
r <- subset[k]
if (r == 0){
no_mov_subset[k] <- 0
} else {
no_mov_subset[k] <- 1
}
sum_no_mov_subset <- sum(no_mov_subset)
data_compress[i] <- sum_no_mov_subset
}
colnames(data_compress) <- c("activity_count")
data_compress <<- data_compress
}
}
Edit: As commented by Heroka and hrbrmstr, this solution is not safe. It is better to assign the output of the function call to a variable:
data_compr <- compress("data_sim", 4/60)

Simulations in R

I'm trying to write a function such as to obtain a test statistic for a vector of size n over 10 simulations. I wrote the following code but I'm not getting the result I need, how can I fix this?
skw=function(n,nsims){
t=numeric(nsims)
for (i in 1:nsims) {
x=rnorm(n)
t[i]=skwness(x)
zscore=t/(6/n)
return(zscore)
}
}
where:
skwness=function(x){
n=length(x)
skew.stat=(1/(n))*(1/(sd(x)^3))*(sum((x-mean(x))^3))
return(skew.stat)
}
Thanks!
You have a couple of issues. The major one is that return should be outside the for loop. Also, you should define t and zscore as vectors, and x as a list.
I think this will work.
Side note: t seems unnecessary in this function. You could get away with using
zscore[i] <- skwness(x[[i]])/(6/n) and get rid of t all together
skwness <- function(x){
n <- length(x)
skew.stat <- (1/(n))*(1/(sd(x)^3))*(sum((x-mean(x))^3))
return(skew.stat)
}
skw <- function(n, nsims){
t <- zscore <- numeric(nsims)
x <- vector("list", nsims)
for (i in 1:nsims) {
x[[i]] <- rnorm(n)
t[i] <- skwness(x[[i]])
zscore[i] <- t[i]/(6/n)
}
return(zscore)
}
Giving it a go:
> x <- rnorm(100)
> skwness(x)
[1] 0.2332121
> skw(100, 10)
[1] 0.6643582 -1.6963196 -2.9192317 -2.7166170 4.9255001 0.0773482 3.9171435
[8] -3.3993994 -2.4258642 0.7075989

for loop storage issue (nested for loops)

I am having difficulty storing all of my data from my middle for loop. when i try and retrieve the data after the outside for loop has run the only data that i am able to attain is the final run. how do i store all of the runs of D in a single matrix?
set.seed(3690)
iterations <- 20
mean_birthrate <- 0.4
stand_dev_birthrate <- 0.1
mean_survival_rate <- 0.68
stand_dev_survival <- 0.07
initial_population <- 100
period <- 20
End_Year <- 2013+period
birthrate <- rnorm(n=1,mean=mean_birthrate,sd=stand_dev_birthrate)
birthrate
survival <- rnorm(n=1,mean=mean_survival_rate,sd=stand_dev_survival)
survival
growth_rate <- birthrate - (1-survival)
growth_rate
for (k in 1:50) {
D <- numeric(period)
D[1] <- initial_population
for (i in 1:period) {
D[i+1] <- D[i] + ((rnorm(n=1,mean=mean_birthrate,sd=stand_dev_birthrate) - (1-rnorm(n=1,mean=mean_survival_rate,sd=stand_dev_survival))) * D[i])
}
print(D)
if (k==1)
plot(D, typ="l",ylab="Number of Bobcats",xlab="Year",ylim=c(50,1700),xaxt='n')
if (k>1)
lines(D,col = rgb(0,0,0,0.1),xaxt='n')
}
if you have nested for loops, you need nested lists (or some other form to capture the n x m many results)
#outter loop
for (i in...)
D[[i]] <- list()
#inner loop
for (j in ...)
D[[i]][[j]] <- value
# or different syntax:
D[[c(i, j)]] <- calue
I had a similar problem, and solved it with a pre-defined variable, like this:
DATA <- list()
j <- 0
for(k in 1:10){
for(i in 1:5){
temp.DATA <- i*k #or whatever the loop does
j <- j+1
DATA[[j]] <- temp.DATA
}
}
DATA2 <- do.call(rbind.data.frame, DATA)
Hope that helps!

Encoding whole numbers in R to a base 62 character vector

What's a quick way to encode either integer values or numeric whole number values in R to a character vector in base 62 encoding, i.e. a string that only contains [a-zA-Z0-9]? Would translating the answer to this question be sufficient?
converting a number base 10 to base 62 (a-zA-Z0-9)
Edited
Here's my solution:
toBase <- function(num, base=62) {
bv <- c(seq(0,9),letters,LETTERS)
r <- num %% base
res <- bv[r+1]
q <- floor(num/base)
while (q > 0L) {
r <- q %% base
q <- floor(q/base)
res <- paste(bv[r+1],res,sep='')
}
res
}
to10 <- function(num, base=62) {
bv <- c(seq(0,9),letters,LETTERS)
vb <- list()
for (i in 1:length(bv)) vb[[bv[i]]] <- i
num <- strsplit(num,'')[[1]]
res <- vb[[num[1]]]-1
if (length(num) > 1)
for (i in 2:length(num)) res <- base * res + (vb[[num[i]]]-1)
res
}
Is that missing anything?
Here's a solution that does base 36 using [0-9A-Z] that could easily be adapted for base 62 using [a-zA-Z0-9]. And yes, it's basically just a translation of the solution to the other question you linked to.
https://github.com/graywh/r-gmisc/blob/master/R/baseConvert.R
Here's a variant of the above code that allows you to convert a vector of numbers to base 16. It's not particularly elegant, as it isn't vectorized, but it gets the job done.
toBase <- function(num, base=16) {
bv <- c(0:9,letters,LETTERS)
r <- list()
q <- list()
res <- list()
for(i in 1:length(num)){
r[i] <- num[i] %% base
res[i] <- bv[r[[i]]+1]
q[i] <- floor(num[i]/base)
while (q[[i]] > 0L) {
r[i] <- q[[i]] %% base
q[i] <- floor(q[[i]]/base)
res[i] <- paste(bv[r[[i]]+1],res[[i]],sep='')
}
}
return(do.call('c', res))
}
To make this more standard, you should implement it in a similar way to the conversion to hexadecimal. (see here for naming.)
as.exindadeomode <- function(x)
{
#Give x a class of "exindadeomode"
#Contents as per as.hexmode
}
format.exindadeomode <- function (x, width = NULL, upper.case = FALSE, ...)
{
#Return appropriate characters
#Contents as per format.hexmode
}
To convert back to integer, just strip the class, using as.integer.

Resources