我有重复的日期,返回的列,然后是我尝试排序的其他变量的许多其他列,然后提取每个日期的排序变量成分的前四分位数的平均回报。有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?
我认为你为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")
按照你的方法逻辑,我们可以做到
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