R: Apply, custom function and Dataframe names

2019-08-30 10:57发布

问题:

I have a data frame Indices containing various names which correspond to data frames (i.e. a name "Index 1" has a corresponding data frame Index 1).

Now I want to run my custom function calcScores over all data frames and add several columns to that data frame. Since I'm not in the global environment I return that "new" data frame and want to assign it back to the original variable Index 1, so Index 1 now has the new data frame with the added columns.

Here's my code (no chance I can make this 100% reproducible since all data is very custom but I hope you understand my question).

# Here the unique Index names are derived and stored
# Problem is the index names are stored as "Index 1", "Index 2" etc.
# Thats why I have to adjust These #titles and create individual data Frames
Indices <- unique(df[1])
apply(unique(df[1]), 1, function(x){
    assign(gsub(" ","",x,fixed=TRUE), subset(df,ticker==x), envir = .GlobalEnv)
})

calcRollingAverage <- function(Parameter, LookbackWindow){
    Output <- rollapply(Parameter, LookbackWindow, mean, fill=NA, partial=FALSE,
                        align="right")
}

calcScores<-function(Index, LookbackWindow){
    Index$PE_Avg = calcRollingAverage(Index$PE_Ratio, LookbackWindow)
    Index$PE_DIV_Avg = Index$PE_Ratio/Index$PE_Avg
    Index$PE_Score = cut(Index$PE_DIV_Avg, breaks=PE_Breaks, labels=Grades)

    return(Index)
}

apply(Indices,1,function(x) assign(gsub(" ","",x,fixed=TRUE), calcScores(get(gsub(" ","",x,fixed=TRUE)),lookback_window)))

I guess my problems are in the apply and with the whole get, assign and gsub story. The scoping is here obviously the issue... At the moment apply gives the following error:

Error: unexpected symbol in:
"apply(Indices,1,function(x) assign(gsub(" ","",x,fixed=TRUE), calcScores(get(gsub(" ","",x,fixed=TRUE)),lookback_window))
apply"

回答1:

Ok solved it...sorry for the post. That is the solution: envir = .GlobalEnv

apply(Indices,1,function(x) assign(gsub(" ","",x,fixed=TRUE), calcScores(get(gsub(" ","",x,fixed=TRUE)),lookback_window),envir = .GlobalEnv))


回答2:

Why don't you just use a for loop, which would help with the scoping problems ? Something like this :

mydf1 <- data.frame(x=1:3, y=2:4)
mydf2 <- data.frame(x=3:5, y=4:6)

indices <- c("mydf1","mydf2")

for (dfname in indices) {
    result <- get(dfname)
    result$z <- result$x+ result$y
    assign(dfname, result)
}


回答3:

Looks like you want to split your data by ticker and apply a function on each splitted element.

This is a job for by or ddply in plyr package.

by(df,df$ticker,FUN=calcScores,LookbackWindow=lookback_window)


标签: r scope apply