在执行函数之前,在summarize_at和funs期间从列中删除na

问题描述 投票:-1回答:2

我有重复的日期,返回的列,然后是我尝试排序的其他变量的许多其他列,然后提取每个日期的排序变量成分的前四分位数的平均回报。有NA,我想在排序时单独忽略每列的NA。

初始数据看起来像这样

  date  return  a   b   c   d
    2/1/18  5   3   5   4   9
    2/1/18  6   2   1   NA  7
    2/1/18  5   NA  6   NA  5
    2/1/18  NA  1   NA  2   NA
    2/1/18  NA  NA  NA  1   NA
    2/2/18  NA  NA  2   NA  NA
    2/2/18  4   10  4   6   NA
    2/2/18  7   5   NA  2   NA
    2/2/18  8   7   7   9   NA
    2/3/18  NA  2   NA  NA  NA
    2/3/18  3   NA  6   5   8
    2/3/18  6   5   2   4   4
    2/3/18  5   8   8   1   9
    2/4/18  6   8   6   3   1
    2/4/18  5   2   5   9   10
    2/4/18  7   4   2   10  8

我希望最终数据如下所示

date    high a return   high b return   high c return   high d return
2/1/18  5   5   5   5
2/2/18  4   8   8   NA
2/3/18  8   5   3   5
2/4/18  6   6   7   5

我试图切换我的代码执行以下一堆不同的变量。

High = df[!is.na(df$a),] %>%
    group_by(date) %>% 
    filter(a > quantile(a, .666)) %>%
    summarise(high_return = mean(return))

我已切换到此代码,但无法复制我在前面的代码中处理na的方式(即!is.na)。

list <- c("a", "b", "c", "d")
High <- df %>%
    group_by(date) %>%
        summarize_at(vars(one_of(list)),
                     funs(HighReturn = mean(return[na.omit(.) > quantile((.), .666, na.rm = TRUE)]))

这不会产生与逐个执行列相同的结果。我也尝试删除na.omit,将na.omit添加到右侧“。”和其他组合。有没有办法在每个列通过函数时生成!is.na?

r function na quantile
2个回答
0
投票

我认为你为date = 2/2/18犯了一个错误,high return c应该是8而不是9

基于以上假设是正确的,您可以执行以下操作

list %>%
    map(~df %>%
        group_by(date) %>%
        filter(!!sym(.x) > quantile(!!sym(.x), 0.666, na.rm = T)) %>%
        summarise(!!sym(paste0("high_return_", .x)) := mean(return))) %>%
    reduce(full_join)
## A tibble: 4 x 5
#  date   high_return_a high_return_b high_return_c high_return_d
#  <fct>          <dbl>         <dbl>         <dbl>         <dbl>
#1 2/1/18             5             5             5             5
#2 2/2/18             4             8             8            NA
#3 2/3/18             5             5             3             5
#4 2/4/18             6             6             7             5

PS。 return在R中不是一个好的列名,因为return是内部R函数的名称。


样本数据

df <- read.table(text =
    "date  return  a   b   c   d
    2/1/18  5   3   5   4   9
    2/1/18  6   2   1   NA  7
    2/1/18  5   NA  6   NA  5
    2/1/18  NA  1   NA  2   NA
    2/1/18  NA  NA  NA  1   NA
    2/2/18  NA  NA  2   NA  NA
    2/2/18  4   10  4   6   NA
    2/2/18  7   5   NA  2   NA
    2/2/18  8   7   7   9   NA
    2/3/18  NA  2   NA  NA  NA
    2/3/18  3   NA  6   5   8
    2/3/18  6   5   2   4   4
    2/3/18  5   8   8   1   9
    2/4/18  6   8   6   3   1
    2/4/18  5   2   5   9   10
    2/4/18  7   4   2   10  8", header = T)


list <- c("a", "b", "c", "d")

0
投票

按照你的方法逻辑,我们可以做到

cols <- c("a", "b", "c", "d")

library(dplyr)

df %>%
  group_by(date) %>%
  summarise_at(vars(cols),
    funs(mean(return[. > quantile(., 0.666, na.rm = TRUE)], na.rm = TRUE)))

#   date       a     b     c     d
#  <fct>  <dbl> <dbl> <dbl> <dbl>
#1 2/1/18     5     5     5     5
#2 2/2/18     4     8     8   NaN
#3 2/3/18     5     5     3     5
#4 2/4/18     6     6     7     5

然而,由于funs正在被dplyr 0.8.0软推,而不是list,如果我们需要重新命名列,我们可以使用

df %>%
  group_by(date) %>%
  summarise_at(vars(cols), 
    list( ~ mean(return[. > quantile(., 0.666, na.rm = T)], na.rm = TRUE))) %>%
  rename_at(vars(cols), list(~ paste0("high_return_", .)))

#   date   high_return_a high_return_b high_return_c high_return_d
#   <fct>          <dbl>         <dbl>         <dbl>         <dbl>
#1 2/1/18             5             5             5             5
#2 2/2/18             4             8             8           NaN
#3 2/3/18             5             5             3             5
#4 2/4/18             6             6             7             5
© www.soinside.com 2019 - 2024. All rights reserved.