[英]Filter all columns in timeseries to keep only top 1/3
我有一个约有100个日期的时间序列,每个日期有50个实体(所以有5,000行)和50列(都是不同的变量)。 如何按唯一日期过滤数据框中的每一列,以使每个日期的每一列的值保持前1/3。 然后获得该组在该日期的平均回报。 谢谢。
我的数据组织如下,但是每列中的数字都是随机的,并且像在“ a”列中的数字一样变化(这是一个示例,实际数据有更多的列和更多的行):
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
我正在尝试将数据过滤到分位数中。 我有一个代码,可以用一种度量过滤到分位数中。 但是,我希望针对多个度量分别过滤结果(即,我希望为一吨列设置“高”组)。
我拥有的一种方法可以使用的代码如下。
列是日期,身份,aa是我要排序的指标
High = df[!is.na(df$a),] %>%
group_by(df.date) %>%
filter(a > quantile(a, .666)) %>%
summarise(high_return = sum(df.return) / length(df.identity)
现在,当我有很多指标需要单独排序时,我想循环使用此方法(即,我不想互相排序,我希望每个指标都单独排序,结果按指标细分)
我希望循环的输出是具有以下格式的新数据帧(其中a_Return是给定日期原始a的前1/3的平均返回):
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
我已经尝试了以下代码,但无法正常工作:
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)}
通过这种尝试,我得到一个错误:“ filter_impl(.data,quo)中的错误:结果的长度必须为20,而不是4719。
我也尝试过:
High %>%
group_by(date) %>%
filter_at(vars(Indicators[i]), any_vars(. > quantile (., .666)))%>%
summarise(!!Indicators[I] := sum(Return) / n())
但是使用该代码,我得到错误“字符串必须与列名匹配。未知列:NA”
我希望High出现一个日期列,然后每个a,b和c列。
如果将过滤和计算组合到一个函数中,则可以将其放入summarize_at
以轻松地将其应用于每个列。 由于您是示例数据,因此无法完全重现,因此我将使用iris
数据集。 在您的情况下,您可以将Species
替换为Date
,并将Petal.Width
为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
使用问题filter
是在管道的每个功能以运行,所以你给任何标准filter_*
将有结果管道输送到之前被应用到整个data.frame summarize_at
。 取而代之的是,我们只使用一个summarize_at
语句,并在应用汇总功能时过滤每一列。
为了更详细地说明这一点, summarize_at
接受两个参数:
第一个参数是vars
函数中包含的?select_helpers
描述的一个或多个变量选择器函数。 在这里,我们使用one_of
,它仅使用列名的向量,但是例如,我们也可以使用matches
来使用常规starts_with
进行选择,或者使用starts_with
来基于前缀进行选择。
第二个参数是funs
函数中包含的要在每个选定列上运行的一个或多个函数调用的列表。 在这里,我们有1个函数调用,我们给它起了名字return
。
像任何tidyverse函数一样,这是在通过管道输入的数据构建的本地环境中进行评估的。因此,像Petal.Width
这样的裸变量名称函数为data$Petal.Width
。 在*_at
函数中, .
表示传入的变量,因此在对Sepal.Length
列进行汇总时:
Petal.Width[. > quantile(., .666)]
手段:
data$Petal.Width[data$Sepal.Length > quantile(data$Sepal.Length, .666)]
最后,由于funs
的函数已命名(即return =
),因此结果汇总列将函数名称( return
)附加到原始列名之后。
如果要在运行这些计算之前删除丢失的数据,可以使用na.omit
NA
值。
要删除所有包含NA
行 ,只需在分组之前通过na.omit
数据:
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
要从正在汇总的每一列中剥离NA
值,您需要将na.omit
移动到na.omit
函数中:
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
下面我们就用大括号来扩展我们在运行功能summarize_at
到多个表达式。 首先,我们去除NA
值,然后计算返回值。 由于此函数位于summarize_at
因此将根据group_by
建立的分组将其应用于每个变量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.