【问题标题】:R: how to count/sum preceding values for certain ID?R:如何对某个 ID 的前值进行计数/求和?
【发布时间】:2019-02-28 08:37:36
【问题描述】:

我有一个数据框 df1,其中包含公司在某一年进行的收购数量的信息。我需要

a) 如果每家公司每年有连续前三年的观测数据,则构建一个虚拟变量

b) 如果该公司年度之前连续三年,则将该三年期间进行的收购数量相加

df1 <- data.frame(ID=c('XXXX-1999','XXXX-2000', 'XXXX-2001', 'YYYY-1999', 
'YYYY-2000', 'ZZZZ-1999','ZZZZ-2000','ZZZZ-2001', 'ZZZZ-2002'),
              No.of.Transactions=c(1,0,2,2,2,4,1,0,3))

其中 ID 是公司在一年中的观察结果。所需的输出如下

# Desired output
# ID | No.of.Transactions | 3 preceding yrs available dummy? | 
No.of.Transactions during 3 preceding yrs
# XXXX-1999 1 0 N/A
# XXXX-2000 0 0 N/A
# XXXX-2001 2 1 3
# YYYY-1999 2 0 N/A
# YYYY-2000 2 0 N/A
# ZZZZ-1999 4 0 N/A
# ZZZZ-2000 1 0 N/A
# ZZZZ-2001 0 1 5
# ZZZZ-2002 3 1 4 

那么如果“前 3 年可用的假人?”列取值为 1,则最后一列应汇总公司在焦点和前两年的所有交易。

提前谢谢你!

【问题讨论】:

  • 为什么最后一行是# ZZZZ-2002 3 1 8?不应该是# ZZZZ-2002 3 1 4吗?如果将ID 列拆分为companyyear,您介意吗?
  • 是的,你完全正确,我现在在原始帖子中进行了编辑。我不介意 ID 列是否分为公司和年份,如果这样更容易!

标签: r


【解决方案1】:

这是怎么回事?我对three_year_trans = trans + lag(trans, 1) + lag(trans, 2) 位不太满意,但这是我想不到的最好的。

如果不明显,lag(year, 2, default = 0) == year - 2 位可确保没有丢失年份(例如,如果公司 XXXXXXXX-1999XXXX-2001XXXX-2002,则不会有 2002 年的总数,因为缺少 2000 年。

library(dplyr)
library(tidyr)

df1 <- data.frame(ID=c('XXXX-1999','XXXX-2000', 'XXXX-2001', 'YYYY-1999', 
                       'YYYY-2000', 'ZZZZ-1999','ZZZZ-2000','ZZZZ-2001', 'ZZZZ-2002'),
                  trans=c(1,0,2,2,2,4,1,0,3))

df1 %>%
  separate(ID, c("company", "year"), "-") %>% 
  mutate(year = as.integer(year)) %>% 
  group_by(company) %>% 
  arrange(year) %>% 
  mutate(three_years_available = (lag(year, 2, default = 0) == year - 2) + 0,
         three_year_trans = if_else(three_years_available == 1,
                                    trans + lag(trans, 1) + lag(trans, 2),
                                    NA_real_)
  ) %>%
  ungroup() %>% 
  arrange(company, year)

【讨论】:

    【解决方案2】:

    您可以使用avezoo::rollsumr 的组合。如果您仍然需要虚拟变量,您可以轻松地从交易总和变量中创建它。

    library(zoo)
    df1$trans.sum <- with(df1, ave(No.of.Transactions, sub("(^.{4}).*", "\\1", ID), 
                               FUN = function(x) rollsumr(x, 3, fill = NA)))
    df1
             ID No.of.Transactions trans.sum
    1 XXXX-1999                  1        NA
    2 XXXX-2000                  0        NA
    3 XXXX-2001                  2         3
    4 YYYY-1999                  2        NA
    5 YYYY-2000                  2        NA
    6 ZZZZ-1999                  4        NA
    7 ZZZZ-2000                  1        NA
    8 ZZZZ-2001                  0         5
    9 ZZZZ-2002                  3         4
    

    【讨论】:

    • 谢谢,这个解决方案非常简单,而且成功了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-10
    • 2021-01-18
    • 2022-11-12
    • 2021-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多