繁体   English   中英

过滤时间序列中的所有列以仅保持前1/3

[英]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.WidthReturn

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM