2017-10-03 2 views
0

J'ai créé une fonction dans R ayant plusieurs arguments. J'aimerais pouvoir appeler ces arguments globalement, à utiliser en dehors de la fonction.Extrait l'argument de fonction local à utiliser globalement dans R

Comment cela peut-il être fait facilement? Je pense peut-être que match.fun() et match.arg() seraient ce qui est nécessaire ici. Ai-je raison?

Ma fonction est la suivante:

HAC.sim <- function(K, N, Hstar, p, probs, perms = 10000){ 

specs <- 1:N 

### Set up a container to hold the identity of each individual from each permutation 

pop <- array(dim = c(c(perms, N), K)) 

### Create an ID for each haplotype 

haps <- as.character(1:Hstar) 

### Assign probabilities of occurrence to each haplotype, ensure they sum to 1 
### This is where we assume we "know" the distribution of haplotypes 
### Here, I have assumed they all occur with equal frequency, but you can change this to   assume some dominant ones and some rare ones, whatever you want 

# probs <- rep(1/Hstar, Hstar) 
probs <- c(0.45, 0.45, rep(0.10/8, 8)) 

### Generate permutations, we assume each permutation has N individuals, and we sample those individuals' haplotypes from our probabilities 

# If K > 1, haplotypes are partitioned into equally-sized subpopulations/demes 
# Can change number of haplotypes in each subpopulation and re-run simulation 
# For each additional, K, add new Ki and new pop[j ,, i] in loop 

for(j in 1:perms){ 
    for(i in 1:K){ 
     if(i == 1){ 
      pop[j, specs, i] <- sample(haps, size = N, replace = TRUE, prob = probs) 
     } 
      else{ 
       pop[j ,, 1] <- sample(haps[K1], size = N, replace = TRUE, prob = probs[K1]) 
       pop[j ,, 2] <- sample(haps[K2], size = N, replace = TRUE, prob = probs[K2]) 
     } 
    } 
} 

### Make a matrix to hold the 1:N individuals from each permutation 

HAC.mat <- array(dim = c(c(perms, N), K)) 

for(k in specs){ 
    for(j in 1:perms){ 
     for(i in 1:K){ 
      ind.index <- sample(specs, size = k, replace = FALSE) ## which individuals will we sample 
      hap.plot <- pop[sample(1:nrow(pop), size = 1, replace = TRUE), ind.index, sample(1:K, size   = 1, replace = TRUE)] ## pull those individuals from a permutation 
      HAC.mat[j, k, i] <- length(unique(hap.plot)) ## how many haplotypes did we get for a given sampling intensity (k) from each ### permutation (j) 
     } 
    } 
} 

### Calculate the mean and CI for number of haplotypes at each sampling intensity (j) 

means <- apply(HAC.mat, MARGIN = 2, mean) 
lower <- apply(HAC.mat, MARGIN = 2, function(x) quantile(x, 0.025)) 
upper <- apply(HAC.mat, MARGIN = 2, function(x) quantile(x, 0.975)) 

d <- data.frame(specs, means, lower, upper) 

### Plot the curve and frequency barplot 

par(mfrow = c(1, 2)) 

for(i in 1:K){ 
    if(i == 1){ 
     plot(specs, means, type = "n", xlab = "Specimens sampled", ylab = "Unique haplotypes", ylim = c(1, Hstar)) 
     polygon(x = c(specs, rev(specs)), y = c(lower, rev(upper)), col = "gray") 
     lines(specs, means, lwd = 2) 
     HAC.bar <- barplot(N*probs, xlab = "Unique haplotypes", ylab = "Specimens sampled", names.arg = 1:Hstar) 
    } 
    else{ 
     plot(specs, means, type = "n", xlab = "Specimens sampled", ylab = "Unique haplotypes", ylim = c(1, max(HAC.mat))) 
     polygon(x = c(specs, rev(specs)), y = c(lower, rev(upper)), col = "gray") 
     lines(specs, means, lwd = 2) 
     HAC.bar <- barplot(N*probs[get(paste0("K", i))], xlab = "Unique haplotypes", ylab = "Specimens sampled", names.arg = get(paste0("K",i))) 
    } 
} 

## Measures of Closeness ## 

cat("\n Mean number of haplotypes sampled: " , max(means)) 
cat("\n Mean number of haplotypes not sampled: " , Hstar - max(means)) 
cat("\n Proportion of haplotypes sampled: " , max(means)/Hstar) 
cat("\n Proportion of haplotypes not sampled: " , (Hstar - max(means))/Hstar) 

cat("\n") 

cat("\n Mean estimate of N*: ", (p*N*Hstar)/max(means)) 

} 

HAC.sim(K = 1, N = 100, Hstar = 10, p = 0.95, probs = probs, perms = 10000) 

Je voudrais l'argument « p » être disponible pour passer à une autre fonction. Dois-je simplement utiliser l'ellipse (...) dans ma fonction pour spécifier des arguments supplémentaires?

+0

Qu'est-ce que vous voulez dire par "appeler ces arguments globalement"? Ce n'est pas clair pour moi ce que tu fais. Peut-être que vous pouvez faire un exemple plus complet [reproductible] (https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example). Je ne suis pas sûr de ce que signifie "sans résultat" dans ce cas. – MrFlick

+0

J'ai juste besoin de passer facilement l'argument de ma fonction à l'extérieur de l'environnement de la fonction. J'ai essayé function.name << - function (...), mais apparemment ceci ne fonctionne que pour les variables locales et pas pour les fonctions entières. –

+0

Cela ressemble exactement à ce que les fonctions sont censées faire. Les fonctions encapsulent typiquement la logique pour la garder de l'environnement global. Il serait beaucoup plus facile de vous aider si vous donniez un exemple de ce que vous espériez. Je ne comprends pas où vous essayez d'exécuter cette tâche. Ecrivez-vous une fonction qui crée une autre fonction? – MrFlick

Répondre

0

Si je comprends bien ce que vous demandez, cela montre comment assigner aux valeurs de l'environnement global les arguments d'une fonction.

> ls() 
character(0) 
> fn <- function(a, b, c) { 
    global_a <<- a 
    global_b <<- b 
    global_c <<- c 
    a*b*c 
} 
> ls() 
[1] "fn" 
> fn(2, 3, 4) 
[1] 24 
> ls() 
[1] "fn"  "global_a" "global_b" "global_c" 
> global_a 
[1] 2 

Cependant, je fortement vous encourage à trouver une alternative autour de ce que vous essayez de résoudre, parce que ce genre d'approche peut conduire à beaucoup de maux de tête sur la route.

Vous pouvez passer les arguments comme un attribut à vos résultats si vous êtes intéressé par seulement quelques-uns des paramètres par exemple:

fn_attr <- function(a, b, c) { 
    res <- a * b * c 
    attr(res, "args") <- list(a = a, c = c) 
    res 
} 

> foo <- fn_attr(2, 3, 4) 
> attr(foo, "args")$a 

ou obtenez toutes les valeurs des arguments:

fn_attr_all <- function(a, b, c) { 
    args_vals <- as.list(environment()) 
    res <- a * b * c 
    attr(res, "args") <- args_vals 
    res 
} 
+0

Merci! Oui, en utilisant << - dans une fonction est une mauvaise pratique à mon avis. Je vais essayer les alternatives que vous suggérez. –