在不考虑特定时间段内的最大值的情况下计算平均值

时间:2020-05-19 11:53:11

标签: r

我有数据框df

 ARTNR AMOUNT    DATE
    20  10      01.12.2019
    12  10      15.12.2019
    12  10      05.12.2019
    20  10      20.12.2019
    12  100     01.02.2020
    20  200     15.02.2020
    20  400     31.08.2019
    12  300     15.07.2019
    ... ...     ...

我想排除特定时间段内的最大值,即从01.11.2019到01.03.2020。

 ARTNR AMOUNT    DATE
    20  10      01.12.2019
    12  10      15.12.2019
    12  10      05.12.2019
    20  10      20.12.2019
    12  100     01.02.2020 --> this is the max value for ARTNR 12
    20  200     15.02.2020 --> this is the max value for ARTNR 20
    20  400     31.08.2019
    12  300     15.07.2019
    ... ...     ...

我要创建数据框df_delta

ARTNR   sum_1   sum_minus_max   average          delta
20      620     420 (620-200)   140 (420/3)      -60 (140-200)
12      420     320 (420-100)   106.66  (320/3)  6.66 (106.66-100)

注释

我们要减去200来计算列delta(感兴趣的时间段内ARTNR 20的最大值)

我们要减去100以计算列delta(感兴趣时间段内ARTNR 12的最大值)

ARTNR =商品编号(有多余的商品编号)

sum_1 =每个AMOUNT的{​​{1}}的总和(我想拥有一个商品编号,没有多余的内容)

ARTNR = sum_minus_max-sum_1的{​​{1}}的最大值在感兴趣的时间段

AMOUNT = ARTNR / n-1 (我要排除最大值)

average = sum_minus_max-在感兴趣的时间段内delta的{​​{1}}的最大值

这与阅读Ian Campbell的输入有关:

average

2 个答案:

答案 0 :(得分:1)

这是使用dplyrlubridate的方法。我们使用dmy来将日期轻松解析为可以执行逻辑比较的形式。我们按ARTNR分组,然后使用case_when创建一个NEWAMOUNT列,当它是日期范围的最大值时,将AMOUNT的值替换为0 。否则,case_when返回AMOUNT

然后,我们使用summerize来计算信息。

library(dplyr)
library(lubridate)
df %>%
  group_by(ARTNR) %>%
  mutate(NEWAMOUNT = case_when(AMOUNT == max(AMOUNT[DATE < dmy("01.03.2020") &
                                                    DATE > dmy("01.11.2019")]) ~ 0,
                               TRUE ~ as.double(AMOUNT))) %>%
  summarize(sum_1 = sum(AMOUNT),
            sum_minux_max = sum(NEWAMOUNT),
            average =  sum(NEWAMOUNT) / (n() - 1),
            delta = average - max(AMOUNT[AMOUNT != NEWAMOUNT]))
## A tibble: 2 x 5
#  ARTNR sum_1 sum_minux_max average  delta
#  <int> <int>         <dbl>   <dbl>  <dbl>
#1    12   420           320    107.   6.67
#2    20   620           420    140  -60 

答案 1 :(得分:0)

Base-R方法

>>> df[['w', 'x']] = pd.DataFrame(df.pop('a')
                                    .astype(str)
                                    .str.strip('(/)')
                                    .str.split(',')
                                    .tolist()).fillna(0).astype(int)

>>> df[['y', 'z']] = pd.DataFrame(df.pop('b')
                                    .astype(str)
                                    .str.strip('(/)')
                                    .str.split(',')
                                    .tolist()).fillna(0).astype(int)

>>> df

   w  x  y  z
0  0  1  1  0
1  1  0  1  2
2  2  0  3  0

输出

df$DATE <- as.Date(df$DATE,"%d.%m.%Y")
data_split <- df[df$DATE >= as.Date("01.11.2019","%d.%m.%Y") & df$DATE <= as.Date("01.03.2020","%d.%m.%Y"),]
data_split <- split(data_split$AMOUNT,df$ARTNR)

df_delta <- data.frame(
    ARTNR = names(data_split),
    sum_1 = sapply(data_split, sum))
    df_delta$sum_minus_max <- df_delta$sum_1 - sapply(data_split, max)
    df_delta$average <- sapply(data_split, function(x) mean(x,-max(x)))
    df_delta$delta <- df_delta$average  - sapply(data_split, max)

编辑:看到想要日期范围的事实之后。我已经编辑