Is there a way how to combine function "cat" with function "replicate" in R?
I want to see number of "loops" R has already made at a particular moment. However, instead of using "for" loop, I prefer to use "replicate". See the simple example below:
Data <- rnorm(20,20,3)
# with for loop
N <- 1000
outcome <- NULL
for(i in 1:N){
Data.boot <- sample(Data, replace=TRUE)
outcome[i] <- mean(Data.boot)
cat("\r", i, "of", N)
}
#the same but with replicate
f <- function() {
Data.boot <- sample(Data, replace=TRUE)
outcome <- mean(Data.boot)
return(outcome)
}
replicate(N, f())
Thus, any ideas how to implement function "cat" with "replicate" (as well as other approaches to see a number of how many times the function of interest has been executed with "replicate") would be very appreciated. Thank you!
As an alternative, you could use sapply instead of replicate:
Data <- rnorm(20,20,3)
N <- 1000
f <- function(i) {
Data.boot <- sample(Data, replace=TRUE)
cat("\r", i, "of", N)
mean(Data.boot)
}
outcome <- sapply(1:N, f)
or alternatively, using plyr, you could use raply with the progress option (if your main purpose is to see how far through you are):
outcome <- plyr::raply(N, mean(sample(Data, replace = TRUE)), .progress = "text")
You could use scoping in the following way:
i = 0
f <- function() {
Data.boot <- sample(Data, replace=TRUE)
outcome <- mean(Data.boot)
i <<- i + 1
print(i)
return(outcome)
}
Related
I am looking for the r equivalent of this simple code in python
mylist = []
for this in that:
df = 1
mylist.append(df)
basically just creating an empty list, and then adding the objects created within the loop to it.
I only saw R solutions where one has to specify the index of the new element (say mylist[[i]] <- df), thus requiring to create an index i in the loop.
Is there any simpler way than that to just append after the last element.
There is a function called append:
ans <- list()
for (i in 1992:1994){
n <- 1 #whatever the function is
ans <- append(ans, n)
}
ans
## [[1]]
## [1] 1
##
## [[2]]
## [1] 1
##
## [[3]]
## [1] 1
##
Note: Using apply functions instead of a for loop is better (not necessarily faster) but it depends on the actual purpose of your loop.
Answering OP's comment: About using ggplot2 and saving plots to a list, something like this would be more efficient:
plotlist <- lapply(seq(2,4), function(i) {
require(ggplot2)
dat <- mtcars[mtcars$cyl == 2 * i,]
ggplot() + geom_point(data = dat ,aes(x=cyl,y=mpg))
})
Thanks to #Wen for sharing Comparison of c() and append() functions:
Concatenation (c) is pretty fast, but append is even faster and therefor preferable when concatenating just two vectors.
There is: mylist <- c(mylist, df) but that's usually not the recommended way in R. Depending on what you're trying to achieve, lapply() is often a better option.
mylist <- list()
for (i in 1:100){
n <- 1
mylist[[(length(mylist) +1)]] <- n
}
This seems to me the faster solution.
x <- 1:1000
aa <- microbenchmark({xx <- list(); for(i in x) {xx <- append(xx, values = i)} })
bb <- microbenchmark({xx <- list(); for(i in x) {xx <- c(xx, i)} } )
cc <- microbenchmark({xx <- list(); for(i in x) {xx[(length(xx) + 1)] <- i} } )
sapply(list(aa, bb, cc), (function(i){ median(i[["time"]]) / 10e5 }))
#{append}=4.466634 #{c}=3.185096 #{this.one}=2.925718
mylist <- list()
for (i in 1:100) {
df <- 1
mylist <- c(mylist, df)
}
Use
first_list = list(a=0,b=1)
newlist = c(first_list,list(c=2,d=3))
print(newlist)
$a
[1] 0
$b
[1] 1
$c
[1] 2
$d
[1] 3
Here's an example:
glmnet_params = list(family="binomial", alpha = 1,
type.measure = "auc",nfolds = 3, thresh = 1e-4, maxit = 1e3)
Now:
glmnet_classifier = do.call("cv.glmnet",
c(list(x = dtm_train, y = train$target), glmnet_params))
I am trying to fill a vector pred_pos with the result pred on each iteration of the for loop. However, my pred_pos vector is never filled. The my_vec object is a list of large character vectors which I don't believe needs to be reproduced for this problem as it is most likely a fundamental indexing error. I just need to know how to populate a vector from this for loop. I can't seem to work out a solution.
pred_pos <- vector("numeric" , 2)
for(i in my_vec) {
for(r in pred_pos) {
inserts <- sapply(i, function(n) { n <- cond_probs_neg[n] } )
pred <- sum(unlist(inserts) , na.rm = T) * apriori_neg
pred_pos[r] <- pred
}
}
Assuming that the rest of your code works, there is no need to explicitly state:
pred_pos <- vector("numeric" , 2)
That creates a numeric vector of length two. You ought to be able to write:
pred_pos <- vector()
Now when you wish to append to the vector you can simply use:
vector[length(vector)+1] <- someData
I believe your code should work if it is adjusted:
pred_pos <- vector()
for(i in my_vec) {
inserts <- sapply(i, function(n) { n <- cond_probs_neg[n] } )
pred <- sum(unlist(inserts) , na.rm = T) * apriori_neg
pred_pos[length(pred_pos)+1] <- pred
}
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
I would like to generate the set with growing number of some representative.
In final I need a matrix or a data.frame, consisting of 100 rows containing i number of representative (in example it's 1). But there is a following error. What is the trick? What I am missing?
Error: no function to return from, jumping to top level
for(i in 1:100) {
x <- c(rep(1,i),rep(100000,(2500-i)))
return(x)
}
Many thanks!
You can only use return within a function. One solution is to create a matrix to store the results in, something like this:
R> m = matrix(0, ncol=100, nrow=2500)
R>
R> for(i in 1:100) {
+ m[,i] = c(rep(1, i), rep(100000, (2500-i)))
+ }
should do the trick. Or using the sapply function:
m1 = sapply(1:100, function(i) c(rep(1, i), rep(100000,(2500-i))))
For info, your rep function can also be simplified to:
rep(c(1, 1000000), c(i, 2500-i))
I'm new to R, and I'm having trouble figuring out how to replace the FOR loop in the function below. The function estimates a population mean. Any help at all would be much appreciated. Thank you!
myFunc<- function(){
myFRAME <- read.csv(file="2008short.csv",head=TRUE,sep=",")
meanTotal <- 0
for(i in 1:100)
{
mySample <- sample(myFRAME$TaxiIn, 100, replace = TRUE)
tempMean <- mean(mySample)
meanTotal <- meanTotal + tempMean
}
cat("Estimated Mean: ", meanTotal/100, "\n") #print result
}
As Rob suggests your loop is unnecessary, but in the spirit of the question the 'replicate()'
function can directly replace your for loop. Like so:
myFunc <- function(){
myFRAME <- read.csv(file="2008short.csv",head=TRUE,sep=",")
meanTotal <- <- mean(replicate(100,mean(sample(myFRAME$TaxiIn,100,T))))
cat("Estimated Mean: ", meanTotal, "\n")
}
Your code takes the mean of 100 sample means, each based on a sample of 100 observations. This is equivalent to taking the mean of 10,000 observations. So the following will do the same thing:
myFunc <- function(){
myFRAME <- read.csv(file="2008short.csv",head=TRUE,sep=",")
meanTotal <- sample(myFRAME#TaxiIn,10000,replace=TRUE)
cat("Estimated Mean: ", meanTotal, "\n")
}