Q:

Filter all columns in timeseries to keep only top 1/3

I have a timeseries with about 100 dates, 50 entities per date (so 5,000 rows) and 50 columns (all are different variables).  How can I filter each column in the data frame, per unique date, to keep the top 1/3 of values for each column on each date.  Then get the average Return for that group for that date.  Thank you. 
My data is organized as follows but the numbers in each column are random and vary like they do in column "a" (this is a sample, the real data has many more columns and many more rows):
Date      Identity       Return   a     b     c    d     e      f... ...z
2/1/19        X                5      75   43     67   85    72     56     92
2/1/19        Y                4      27   43     67   85    72     56     92
2/1/19        Z                7      88   43     67   85    72     56     92
2/1/19        W               2      55   43     67   85    72     56     92
2/2/19         X               7      69   43     67   85    72     56     92
2/2/19         Y               8      23   43     67   85    72     56     92
2/3/19         X                2      34   43     67   85    72     56     92
2/3/19         Y                3      56   43     67   85    72     56     92
2/3/19         Z                4      62   43     67   85    72     56     92
2/3/19         W               4      43   43     67   85    72     56     92
2/3/19         U                4      26   43     67   85    72     56     92
2/4/19         X                6      67   43     67   85    72     56     92
2/4/19         Y                1      78   43     67   85    72     56     92
2/5/19         X                4      75   43     67   85    72     56     92
2/7/19         X                5      99   43     67   85    72     56     92
2/7/19         Y                 4      72   43     67   85    72     56     92
2/7/19         Z                  4      45   43     67   85    72     56     92

I am trying to filter data into quantiles.  I have a code that works for filtering into quantiles for one measure.  However I want filtered results for many measures individually (i.e. I want a “high” group for a ton of columns). 
The code that I have that works for one measure is as follows. 
Columns are date, identity, and a a is the indicator I want to sort on
High = df[!is.na(df$a),] %>%
    group_by(df.date) %>% 
    filter(a > quantile(a, .666)) %>%
    summarise(high_return = sum(df.return) / length(df.identity)

Now I want to loop this for when I have many indicators to sort on individually (I.e. I do not want to sort within one another, I want each sorted separately and the results to be broken out by indicator)
I want the output of the loop to be a new data frame with the following format (where a_Return is the average return of the top 1/3 of the original a's on a given date):
Date       a_Return    b_Return    c_Return
2/1/19       6.             7           3
2/3/19       4.             2           5
2/4/19       2.             4           6

I have tried the code below without it working:
Indicators <- c(“a”, “b”, “c”)

for(i in 1:length(Indicators)){
     High = df %>%
        group_by(df.date) %>% 
        filter(High[[I]] > quantile(High[[i]], .666)) %>%
        summarise(g = sum(df.return) / length(df.identity)}

With this attempt I get the error: "Error in filter_impl(.data, quo) : Result must have length 20, not 4719.  
I also tried:
High %>%
    group_by(date) %>%
    filter_at(vars(Indicators[i]), any_vars(.  > quantile (.,  .666)))%>%
    summarise(!!Indicators[I] := sum(Return) / n())

but with that code I get the error "Strings must match column names.  Unknown Columns: NA"
I want High to turn up with a date column and then a column for each a, b, and c.

A:

If you combine the filtering and calculations into a single function, then you can put that into summarize_at to apply it easily to each column.  Since you're example data isn't fully reproducible, I'll use the iris dataset.  In your case, you'd replace Species with Date, and Petal. Width with Return:
library(dplyr)
top_iris <- iris %>%
    group_by(Species) %>%
    summarize_at(vars(one_of('Sepal. Length', 'Sepal. Width', 'Petal. Length')),
                 funs(return = sum(Petal. Width[.  > quantile(.,  .666)]) / length(Petal. Width[.  > quantile(.,  .666)])))

top_iris

# A tibble: 3 x 4
  Species    Sepal. Length_return Sepal. Width_return Petal. Length_return
  <fct>                    <dbl>              <dbl>               <dbl>
1 setosa                   0.257              0.262               0.308
2 versicolor               1.44               1.49                1.49 
3 virginica                2.1                2.22                2.09 

The problem with using filter is that each function in the pipe runs in order, so any criteria you give to filter_* will have to be applied to the whole data.frame before the result is piped into summarize_at.  Instead, we just use a single summarize_at statement, and filter each column as the summarization function is applied to it. 

To explain this in more detail, summarize_at takes 2 arguments: 
The first argument is one or more of the variable selector functions described in ? select_helpers, enclosed in the vars function.  Here we use one_of which just takes a vector of column names, but we could also use matches to select using a regular expession, or starts_with to choose based on a prefix, for example. 
The second argument is a list of one or more function calls to be run on each selected column, enclosed in the funs function.  Here we have 1 function call, to which we've given the name return. 
Like with any tidyverse function, this is evaluated in a local environment constructed from the data piped in.  So bare variable names like Petal. Width function as data$Petal. Width.  In *_at functions, the .  represents the variable passed in, so when the Sepal. Length column is being summarized:
Petal. Width[.  > quantile(.,  .666)]

means:
data$Petal. Width[data$Sepal. Length > quantile(data$Sepal. Length, .666)]

Finally, since the function in funs is named (that's the return =), then the resulting summary columns have the function's name (return) appended to the original column names. 

If you want to remove missing data before running these calculations, you can use na.omit to strip out NA values. 
To remove all rows containing NA, just pipe your data through na.omit before grouping:
iris2 <- iris
iris2[c(143:149), c(1:2)] <- NA

iris2 %>%
    na.omit() %>%
    group_by(Species) %>%
    summarize_at(vars(one_of('Sepal. Length', 'Sepal. Width', 'Petal. Length')),
                 funs(return = sum(Petal. Width[.  > quantile(.,  .666)]) / length(Petal. Width[.  > quantile(.,  .666)])))

  Species    Sepal. Length_return Sepal. Width_return Petal. Length_return
  <fct>                    <dbl>              <dbl>               <dbl>
1 setosa                   0.257              0.262               0.308
2 versicolor               1.44               1.49                1.49 
3 virginica                2.09               2.19                2.07 

To strip NA values from each column as it's being summarized, you need to move na.omit inside the summarize function:
iris2 %>%
    group_by(Species) %>%
    summarize_at(vars(one_of('Sepal. Length', 'Sepal. Width', 'Petal. Length')),
                 funs(return = {
                     var <- na.omit(.) 
                     length(Petal. Width[var > quantile(var, .666)])
                 }))
# A tibble: 3 x 4
  Species    Sepal. Length_return Sepal. Width_return Petal. Length_return
  <fct>                    <dbl>              <dbl>               <dbl>
1 setosa                   0.257              0.262               0.308
2 versicolor               1.44               1.49                1.49 
3 virginica                2.11               2.2                 2.09 

Here we use curly braces to extend the function we run in summarize_at to multiple expressions.  First, we strip out NA values, then we calculate the return values.  Since this function is in summarize_at it gets applied to each variable based on the grouping established by group_by.