Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
145 views
in Technique[技术] by (71.8m points)

r - How do I run a function for multiple parameters, return an output and have this in a single data table?

I have developed code that calculates a value for a given set of parameters, this works for a single set of parameters.

library(spatstat)
library(ggplot2)
library(dplyr)
library(tidyr)

#Generating a clustered landscape
dim <- 2000
radiusCluster<-100
lambdaParent<-.02
lambdaDaughter<-30
hosts<-900
randmod<-0

numbparents<-rpois(1,lambdaParent*dim)

xxParent<-runif(numbparents,0+radiusCluster,dim-radiusCluster)
yyParent<-runif(numbparents,0+radiusCluster,dim-radiusCluster)

numbdaughter<-rpois(numbparents,(lambdaDaughter))
sumdaughter<-sum(numbdaughter)

theta<-2*pi*runif(sumdaughter)
rho<-radiusCluster*sqrt(runif(sumdaughter))

xx0=rho*cos(theta)
yy0=rho*sin(theta)

xx<-rep(xxParent,numbdaughter)
yy<-rep(yyParent,numbdaughter)

xx<-xx+xx0

yy<-yy+yy0
cds<-data.frame(xx,yy)
is_outlier<-function(x){
  x > dim| x < 0
}
cds<-cds[!(is_outlier(cds$xx)|is_outlier(cds$yy)),]
sampleselect<-sample(1:nrow(cds),hosts,replace=F)
cds<-cds%>%slice(sampleselect)

randfunction<-function(x){
  x<-runif(length(x),0,dim)
}
randselect<-sample(1:nrow(cds),floor(hosts*randmod),replace=F)
cds[randselect,]<-apply(cds[randselect,],1,randfunction)
landscape<-ppp(x=cds$xx,y=cds$yy,window=owin(xrange=c(0,dim),yrange=c(0,dim)))
ggplot(data.frame(landscape))+geom_point(aes(x=x,y=y))+coord_equal()+theme_minimal()

#Calculating a metric for clustering


kk<-Kest(landscape)
plot(kk)
kk_iso<-kk$iso
kk_pois<-kk$theo

kk_div_na<-kk_iso/kk_pois
kk_div_0<-replace_na(kk_div_na,0)
kk_mean<-round(mean(kk_div_0),3)

So I can say for radiusCluster of 100 and randmod of 0, I get a kk_mean of "value". I want to use radiusCluster and randmod as my variables and run this experiment for a set of these variables. I begin by generating the data table that I want.


random_parameter<-rep(c(0,.5,1),3)
radiusCluster_parameter<-rep(c(100,300,600),each=3)
Cluster_metric<-rep(NA,length(radiusCluster_parameter))
parameter_table<-data.frame(random_parameter,radiusCluster_parameter,Cluster_metric)
colnames(parameter_table)<-c("r", "rho", "sigma")

Here r is randmod, rho is radiusCluster and sigma is kk_mean.

Then I create a function of the above code for generating the clustered landscape and calculating the metric.

cluster_function <- function (dim,
                     lambdaParent,
                     lambdaDaughter,
                     hosts,
                     randmod,
                     radiusCluster) {
  numbparents <- rpois(1, lambdaParent * dim)
  
  xxParent <- runif(numbparents, 0 + radiusCluster, dim - radiusCluster)
  yyParent <- runif(numbparents, 0 + radiusCluster, dim - radiusCluster)
  
  numbdaughter <- rpois(numbparents, (lambdaDaughter))
  sumdaughter <- sum(numbdaughter)
  
  theta <- 2 * pi * runif(sumdaughter)
  rho <- radiusCluster * sqrt(runif(sumdaughter))
  
  xx0 = rho * cos(theta)
  yy0 = rho * sin(theta)
  
  xx <- rep(xxParent, numbdaughter)
  yy <- rep(yyParent, numbdaughter)
  
  xx <- xx + xx0
  
  yy <- yy + yy0
  cds <- data.frame(xx, yy)
  is_outlier <- function(x) {
    x > dim | x < 0
  }
  cds <- cds[!(is_outlier(cds$xx) | is_outlier(cds$yy)), ]
  sampleselect <- sample(1:nrow(cds), hosts, replace = F)
  cds <- cds %>% slice(sampleselect)
  
  randfunction <- function(x) {
    x <- runif(length(x), 0, dim)
  }
  randselect <- sample(1:nrow(cds), floor(hosts * randmod), replace = F)
  cds[randselect, ] <- apply(cds[randselect, ], 1, randfunction)
landscape<-ppp(x=cds$xx,y=cds$yy,window=owin(xrange=c(0,dim),yrange=c(0,dim)))
ggplot(data.frame(landscape))+geom_point(aes(x=x,y=y))+coord_equal()+theme_minimal()

kk<-Kest(landscape)
plot(kk)
kk_iso<-kk$iso
kk_pois<-kk$theo

kk_div_na<-kk_iso/kk_pois
kk_div_0<-replace_na(kk_div_na,0)
kk_mean<-round(mean(kk_div_0),3)
}

I then try running cluster_function for a set of parameters, however, this does not work.

cluster_function(dim <- 2000,
                       lambdaParent <-.02,
                       lambdaDaughter<-30,
                      hosts<-900,
                      randmod<-0,
                      radiusCluster<-0)

The parameters are defined in the global environment but nothing happens. So I decide to remove the landscape and ggplot command from the function and call the function to an output. Then hopefully the output will be data frame of the co ordinates that I generated in cds and can be used in a ppp() function and be plottable.

output<-cluster_function(dim <- 2000,
                       lambdaParent <-.02,
                       lambdaDaughter<-30,
                      hosts<-900,
                      randmod<-0,
                      radiusCluster<-0)

Output is numeric (empty). How can I get the function to work for the parameters in the cluster_function() and is it possible to run this for multiple parameters? I was thinking something along the lines of:

for (i in length(parameter_table)){
cluster_function(dim <- 2000,
                       lambdaParent <-.02,
                       lambdaDaughter<-30,
                      hosts<-900,
                      randmod<-parameter_table[i,"r"],
                      radiusCluster<-parameter_table[i,"rho"])
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I then try running cluster_function for a set of parameters, however, this does not work

It looks like it's working to me ;) Do you want the ggplot to be printed? You can addp <- ggplot(...) followed be print(p) to see it (you may need to refresh the plot viewer...).

Output is numeric (empty). How can I get the function to work

Add an explicit return: return(cds)

And you can of course run the function multiple times. A for loop works, or you could check out purrr::pmap() or mapply(). Good luck!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...