2017-05-05 3 views
0

J'ai cherché haut et bas pour la réponse à ce problème (apparemment simple), mais est venu vide alors j'espère que quelqu'un peut m'aider ou me pointer dans la bonne direction.Comment appliquer une fonction "compliquée" définie par l'utilisateur sur chaque élément d'un dînette

J'ai un sous-modèle assez compliqué que je veux appliquer à un ensemble de données, mais si j'utilise simplement utiliser muter, j'obtiens une erreur Variables must be length 1 or 21. ajoutant Rowwise() ne semble pas l'impact.

Permettez-moi de l'illustration suivante stupide du problème:

myData <- tibble(x=10:20, y=c("a", "b","a", "b","a", "b","a", "b","a", "b","a")) 

staticData <- tibble(x=0:100, y=c("a"),f=x/100) %>% union (tibble(x=0:100, y=c("b"),f=x/1000)) 

ComplicatedFunction <- function(mystaticData, myx, myy) { 
    #make the base table 
    myBaseTable <- tibble(
    y = myy, 
    x = c(myx:(myx + 20)) 
) 
    #add f rates 
    myBaseTable <- left_join(myBaseTable,mystaticData) 
    #add stuff 
    myBaseTable <- myBaseTable %>% 
    mutate(z = 1 - (f * 0.8)) %>% 
    mutate(zCumulative = cumprod(z)) 
    #Calculate the thing 
    myCalculatedThing <- sum(myBaseTable$zCumulative) 

    return(myCalculatedThing) 
} 

#This is what I want to do 
myData %>% mutate(newcol = ComplicatedFunction(mystaticData = staticData, 
               myx = x, 
               myy = y)) 
#this works 
ComplicatedFunction(mystaticData = staticData, 
        myx = 19, 
        myy = "b") 
ComplicatedFunction(mystaticData = staticData, 
        myx = 20, 
        myy = "a") 

#This works (but would be silly as I want the function to be evaluated for each line) 
myData %>% mutate(newcol = ComplicatedFunction(mystaticData = staticData, 
               myx = 15, 
               myy = "a")) 

#This no longer works, but I dont understand what I am doing wrong 
myData %>% mutate(newcol = ComplicatedFunction(mystaticData = staticData, 
               myx = x, 
               myy = "a")) 

#I tried rowwise(), but this doesnt seem to work either 
myData %>% rowwise() %>% mutate(newcol = ComplicatedFunction(mystaticData = staticData, 
               myx = x, 
               myy = y)) 

J'espère que quelqu'un peut me expliquer ce que je fais mal ici.

Merci beaucoup d'avance!

Sylvain

Répondre

2

Vous pouvez le faire en créant une nouvelle fonction à l'aide partial:

library(purrr) 
newCF <- partial(ComplicatedFunction, mystaticData = staticData) 
myData %>% rowwise() %>% mutate(newcol = newCF(myx = x, 
              myy = y)) 
+0

Un grand merci @Student. cela résout le problème. Je ne comprends pas pourquoi il est nécessaire d'ajouter partiel (après avoir vérifié l'aide). Si cela ne vous pose pas trop de problèmes, pourriez-vous me montrer la documentation expliquant pourquoi cela fonctionne? – Sylvain

+0

'df%>% mutate' n'a pas fonctionné car' ComplicatedFunction' n'est pas une fonction vectorisée. C'est pourquoi vous voulez utiliser 'rowwise' par exemple. La raison pour laquelle j'ai proposé d'utiliser 'partial' est que' staticData' est fixe et ne devrait pas être traité en ligne. Donc partiel créé une nouvelle fonction où staticData déjà rempli et maintenant la nouvelle fonction ont seulement les deux variables "dynamiques" 'x' et' y'. (Notez que maintenant, quand je relance votre code, la dernière ligne de code fonctionne donc le problème a disparu et je ne suis pas tout à fait sûr pourquoi, donc je ne peux pas commenter plus sur le.) – student