【问题标题】:How to add row values based on specific column conditions?如何根据特定列条件添加行值?
【发布时间】:2021-04-29 21:25:45
【问题描述】:

我有一个数据框 X,其中包含 20 只不同的股票,观察它们各自 10 年的每日回报。数据框 X 如下所示:

Stock Date Return
BKR 01.02.2002 2%
BKR 02.02.2002 -1%
BKR 03.02.2002 1%
BKR 04.02.2002 2.5%
BKR 05.02.2002 -3%
BKR 01.03.2002 2%
BKR 02.03.2002 1%
BKR 03.03.2002 -2%

我希望将这些每日收益转换为季度收益,从而增加 3 个月的每日收益(因为这些是连续收益,它们是相加的)。条件应该是库存相同(示例仅显示 BKR 和 USP,但我有 20 个不同的)。换句话说,我希望数据框 Y 看起来像这样:

Stock Quarter Return
BKR 01.2002 4%
BKR 02.2002 -15%
BKR 03.2002 11%
BKR 04.2002 2%
BKR 01.2003 -31%
BKR 02.2003 21%
BKR 03.2003 12%
BKR 04.2003 -2%
USP 01.2002 1%
USP 02.2002 -13%
USP 03.2002 12%
USP 04.2002 8%
USP 01.2003 -13%
USP 02.2003 2%
USP 03.2003 14%
USP 04.2003 -3%

【问题讨论】:

  • 您确定这些百分比是累加的吗?考虑股票 X;起价 100 美元。第 1 天上涨 10%,现在为 110 美元。第 2 天它损失了 10%,现在是 99 美元。这不是 0%,正如简单添加百分比所暗示的那样。如果我错了或误解了您的问题,请纠正我。
  • 当我使用 ln(y/y-1) 计算连续回报时,回报是相加的。您可以尝试使用您提供的数字执行操作:ln(110/100) + ln(99/110) = ln(99/100)

标签: r


【解决方案1】:

考虑使用lubridate 和dplyr 的以下解决方案:

#make a sample dataframe
x <- data.frame(Stock = c(rep('BKR',12), rep('TMP',12)),
                Date = c('01.01.2002','01.02.2002','01.03.2002','01.04.2002','01.05.2002','01.06.2002','01.07.2002','01.08.2002','01.09.2002','01.10.2002','01.11.2002','01.12.2002','01.01.2003','01.02.2003','01.03.2003','01.04.2003','01.05.2003','01.06.2003','01.07.2003','01.08.2003','01.09.2003','01.10.2003','01.11.2003','01.12.2003'),
                Return = c("2%","-4%","6%","1.2%","-1%","-1%","1%","2%","3%","8%","-3%","2%","12%","-8%","7%","13%","-24%","-1%","5%","6%","3%","2%","-3%","8%"))
x$Return <-  as.numeric(sub("%", "", x$Return, fixed=TRUE))/100
x$Date <- as.Date(x$Date, format='%d.%m.%Y')
#summarise the data
result <- x %>%
  group_by(quarter(Date, with_year = T), Stock) %>%
  summarize(year = year(Date), 
            quarter = quarter(Date),
            additive_return = sum(Return), 
            .groups = 'drop') %>% 
  unique() %>% 
  select(-`quarter(Date, with_year = T)`) %>% 
  mutate(additive_return = paste0(formatC(additive_return * 100, format = "f", digits = 2, ), "%"))

你会得到以下输出:

> result
# A tibble: 8 x 4
  Stock  year quarter additive_return
  <chr> <dbl>   <int> <chr>          
1 BKR    2002       1 4.00%          
2 BKR    2002       2 -0.80%         
3 BKR    2002       3 6.00%          
4 BKR    2002       4 7.00%          
5 TMP    2003       1 11.00%         
6 TMP    2003       2 -12.00%        
7 TMP    2003       3 14.00%         
8 TMP    2003       4 7.00% 

【讨论】:

    【解决方案2】:

    使用dplyr,您可以先mutate日期,以便它们仅按年和月区分,然后group_byStock和Date,最后计算总和Returns组:

    library(dplyr)
    df %>%
      mutate(Date = sub("(\\d{4})-(\\d{2}).*", "\\2.\\1", Date)) %>%
      group_by(Stock, Date) %>%
      summarise(Return = sum(as.numeric(sub("%", "", Return))))
    # A tibble: 2 x 3
    # Groups:   Stock [2]
      Stock Date    Return
      <chr> <chr>    <dbl>
    1 A     01.2000    6.5
    2 B     02.2000    2.3
    

    数据:

    df <- data.frame(
      Stock = c(rep("A",3), rep("B",3)),
      Date = c(seq(as.Date("2000-1-1"), as.Date("2000-1-3"), "days"),
               seq(as.Date("2000-2-1"), as.Date("2000-2-3"), "days")),
      Return = c("4%", "-1%", "3.5", "2%", "4%", "-3.7%")
    )
    

    【讨论】:

      【解决方案3】:

      首先将Return col 转换为数字:

      df$Date = as.Date(df$Date, "%d.%m.%y")
      df$Q = quarters(df$Date)
      aggregate(Return~Stock + Q, df, sum)
      
      Stock  Q     Return
      BKR    Q1    2.5
      

      【讨论】:

        猜你喜欢
        • 2019-08-25
        • 2020-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-25
        • 1970-01-01
        • 1970-01-01
        • 2023-03-30
        相关资源
        最近更新 更多