使用R对面板数据中的横截面单位的值求和

ste*_*eve 2 r data-manipulation

所有,

我工作的公司给了我这些数据.简而言之,它是TSCS数据,公司作为横截面单位,时间单位为财政年度.每家公司都有各种账户.我有兴趣为特定公司创建每个帐户的总支出.

我可以提供下面数据的简单说明.让我们firm感兴趣的截单元.每个firm都有公司花钱的各种账户.有些账户对所有公司都很常见,有些则是独一无二的.并非每个人firm都有在一年中花在账户上的钱.事实上,有些人直到数据之后才有资格获得账户,而其他人则退出(因此,面板数据可能被认为是不平衡的).因此,我提供的数据中的NA可以被视为0,尽管它有点问题.有些公司在某一年有资格但没有在账户中收款.由于辍学或迟到,其他公司不合格.

数据看起来像这样,它是以宽格式提供给我的.这是一个简化版本的插图.在此图示中,firm=B在1990 firm=C财政年度没有资格获得帐户,并在1992财年退出.

firm   account   FY1990 FY1991 FY1992
A     Account 1    500    900   1000
A     Account 2     30     40     40
A     Account 3     NA     60     20
A     Account 4     NA     35     NA
B     Account 1     NA    340     60
B     Account 2     NA    500    800
B     Account 3     NA    800     NA
B     Account 4     NA     60   1000
C     Account 1   1000    400     NA
C     Account 5    500     60     NA
C     Account 8     60   1000     NA
D     Account 1    400    400    400
D     Account 2     NA   1000   1000
D     Account 3    300     40    300
D     Account 6     NA    300    300
D     Account 7    900    900   1000
D     Account 8   1000   1200   1500
Run Code Online (Sandbox Code Playgroud)

我想做的(并被告知要做)是修改这些数据,使它看起来像这样:

firm   account   FY1990 FY1991 FY1992
A     Account 1    500    900   1000
A     Account 2     30     40     40
A     Account 3     NA     60     20
A     Account 4     NA     35     NA
A      TOTAL       530   1035   1060
B     Account 1     NA    340     60
B     Account 2     NA    500    800
B     Account 3     NA    800     NA
B     Account 4     NA     60   1000
B      TOTAL        NA   1700   1860
C     Account 1   1000    400     NA
C     Account 5    500     60     NA
C     Account 8     60   1000     NA
C      TOTAL      1560   1460     NA
D     Account 1    400    400    400
D     Account 2     NA   1000   1000
D     Account 3    300     40    300
D     Account 6     NA    300    300
D     Account 7    900    900   1000
D     Account 8   1000   1200   1500
D      TOTAL      2600   3840   4500
Run Code Online (Sandbox Code Playgroud)

我可以在Excel或其他电子表格程序中轻松地执行此操作,但这将是乏味的,并且它会比我使用R对此进行编程时引发更多人为错误.我并不反对使用总计创建新数据框,而不是尝试在给定公司的所有帐户下添加一行.如果给定公司的总额不符合某一财政年度的账户,则可能更容易设置0.我总是可以将一些零重新编码为NAs,并自动执行该过程.

我的假设是这需要一个循环,但我是R编程的新手.任何投入将不胜感激.

下图中可重复使用的代码如下图所示.

firm <- c("A","A","A","A","B","B","B","B","C","C","C","D","D","D","D","D","D")
account <- c("Account 1","Account 2","Account 3","Account 4","Account 1","Account 2","Account 3","Account 4","Account 1","Account 5","Account 8","Account 1","Account 2","Account 3","Account 6","Account 7","Account 8")
FY1990 <- c(500,30,NA,NA,NA,NA,NA,NA,1000,500,60,400,NA,300,NA,900,1000)
FY1991 <- c(900,40,60,35,340,500,800,60,400,60,1000,400,1000,40,300,900,1200)
FY1992 <- c(1000,40,20,NA,60,800,NA,1000,NA,NA,NA,400,1000,300,300,1000,1500)

Data=data.frame(firm=firm, account=account, FY1990=FY1990, FY1991=FY1991, FY1992=FY1992)
summary(Data)
Data
Run Code Online (Sandbox Code Playgroud)

Fra*_*ank 5

这是一种data.table方法:

library(data.table)
dt <- data.table(Data)

dt[, rbind(.SD,
           c("TOTAL",
             lapply(.SD[, grepl("^FY[0-9]+", names(.SD)), with = F],
                    function(x){sum(x, na.rm = !all(is.na(x)))}
                   )),
           use.names = F),
     by = firm]
Run Code Online (Sandbox Code Playgroud)

这样做如下:我们遍历by = firmfirm (),对于每个公司我们堆栈(rbind)......

  • 与该公司相关的数据子集(.SD)
  • 一个向量开头"TOTAL",其余由长lapply调用创建.

lapply只与一个公司在一个时间相关的数据进行操作.该数据存储在.SD上面提到的特殊临时data.table 中.列名也可以直接命名(但不在此示例中).

lapply电话的工作原理如下:我们遍历向量的列表(通过选择使用将我们的名字列中选择grepl正则表达式测试),并为每个向量我们应用的特殊变体sum的功能.

sum函数的这个变体查看完整的向量x,其中 - 从我们迭代的列表中选择此向量,并且一次只有一个公司关联的行 - 并检查是否存在任何非NA条目x(即,如果!all(is.na(x))).如果存在,则将这些条目相加,将任何NAs视为零(自na.rm=TRUE); 如果没有,它返回NA(因为na.rm=FALSE我们有NAs).

有关na.rm参数的详细信息,请查看?sum.类似地,通过使用或搜索可以找到有关上述函数(grepl,lapply...)的详细信息.?term?"term"

by=firm然后,该选项将公司的结果堆叠起来,并将"公司"作为第一列.

这是结果:

    firm   account FY1990 FY1991 FY1992
 1:    A Account 1    500    900   1000
 2:    A Account 2     30     40     40
 3:    A Account 3     NA     60     20
 4:    A Account 4     NA     35     NA
 5:    A     TOTAL    530   1035   1060
 6:    B Account 1     NA    340     60
 7:    B Account 2     NA    500    800
 8:    B Account 3     NA    800     NA
 9:    B Account 4     NA     60   1000
10:    B     TOTAL     NA   1700   1860
11:    C Account 1   1000    400     NA
12:    C Account 5    500     60     NA
13:    C Account 8     60   1000     NA
14:    C     TOTAL   1560   1460     NA
15:    D Account 1    400    400    400
16:    D Account 2     NA   1000   1000
17:    D Account 3    300     40    300
18:    D Account 6     NA    300    300
19:    D Account 7    900    900   1000
20:    D Account 8   1000   1200   1500
21:    D     TOTAL   2600   3840   4500
    firm   account FY1990 FY1991 FY1992
Run Code Online (Sandbox Code Playgroud)

您必须先安装并加载data.table包.

  • 弗兰克,我会用这些修正来编辑你的答案. (2认同)