1

我正在研究一个data.frame由股票每年股息组成的 R(我有 60 列股票和行中的通常日历)。支付股息时,我有这个数字,否则有一个NA

基本上,这就是我的 Data.frame 的样子

           BARC LN      BARN SE  BAS GY  BATS LN 
1999-01-01      0.26       NA      NA
1999-01-02       NA       0.56     0.35     NA
1999-01-03       NA        NA      NA       NA
2000-01-04       NA        NA      0.40     NA
1999-01-05      0.23      0.28     NA       NA
2001-01-06       NA        NA      NA       NA
2001-01-07      0.85       NA     0.15      NA

我想获得每只股票每年支付的股息金额,以计算股息收益率,最后得到一个数据;如下图所示:

           BARC LN   BARN SE  BAS GY  BATS LN 
   1999       NA        NA      NA       NA
   2000       NA        NA      NA       NA
   2001       NA        NA      NA       NA

我怎样才能做到这一点?

4

2 回答 2

2

因此,假设您的数据位于 data.frame 中,就像您在上面发布的那样div

div <- structure(list(barc.ln = c(0.26, NA, NA, NA, 0.23, NA, 0.85), 
    barn.se = c(NA, 0.56, NA, NA, 0.28, NA, NA), bas.gy = c(NA, 
    0.35, NA, 0.4, NA, NA, 0.15), bats.ln = c(NA, NA, NA, NA, 
    NA, NA, NA)), .Names = c("barc.ln", "barn.se", "bas.gy", 
"bats.ln"), row.names = c("1999-01-01", "1999-01-02", "1999-01-03", 
"2000-01-04", "1999-01-05", "2001-01-06", "2001-01-07"), class = "data.frame")

正如您所做的那样,您可以从您的row.names:

div$years <- as.POSIXlt(row.names(div))$year + 1900

plyr和包在reshape2这里运行良好,我认为使代码特别清晰。具体来说,我将使用melt使数据变长,然后ddply分成组和sum红利:

library(plyr)
library(reshape2)
div.melt <- melt(div, id.vars='years')
div.sum <- ddply(div.melt, 
                 .(years, variable), 
                 summarise, 
                 dividend = sum(value, na.rm=TRUE))

> div.sum
 years variable dividend
1   1999  barc.ln     0.49
2   1999  barn.se     0.84
3   1999   bas.gy     0.35
4   1999  bats.ln     0.00
5   2000  barc.ln     0.00
6   2000  barn.se     0.00
7   2000   bas.gy     0.40
8   2000  bats.ln     0.00
9   2001  barc.ln     0.85
10  2001  barn.se     0.00
11  2001   bas.gy     0.15
12  2001  bats.ln     0.00
> 

然后,您可以使用reshape2调用中的另一个函数来cast“宽”格式化您的数据:

> dcast(div.sum, years ~ variable, value.var='dividend')
  years barc.ln barn.se bas.gy bats.ln
1  1999    0.49    0.84   0.35       0
2  2000    0.00    0.00   0.40       0
3  2001    0.85    0.00   0.15       0
> 
于 2012-06-25T14:35:18.743 回答
1

我认为你可以很容易地使用 by() 做到这一点。这就是我的做法。我已将每个块以及每个块下方的说明放在一起。

dividends <- data.frame(barc_ln=c(0.26,NA,NA,NA,0.23,NA,0.85),
                        barn_se=c(NA,0.56,NA,NA,0.28,NA,NA),
                        bas_gy=c(NA,0.35,NA,0.40,NA,NA,0.15),
                        bats_ln=c(NA,NA,NA,NA,NA,NA,NA),
                        row.names=c("1999-01-01","1999-01-02","1999-01-03","2000-01-04","1999-01-05","2001-01-06","2001-01-07"))

这只会创建您提供的原始数据框。

dividends[,"dates"] <- as.Date(row.names(dividends))
dividends <- dividends[order(dividends[,"dates"]),]
dividends[,"year"] <- format(dividends$dates,"%Y")

这将获取行名称日期,然后将它们转换为数据框中的新列(“日期”)。然后,我们按日期排序数据框(不一定需要,但我发现它更直观)并使用格式提取年份(作为一个字符,请注意)。

div_output <- data.frame(row.names=unique(dividends$year))

接下来,我创建将接收数据的输出数据框。我对 year 变量使用 unique() 函数来获取唯一的年份向量。它们已经被订购(订购数据框的一个优点)。

for(x in 1:4) {
    div_output[,x] <- by(dividends[,x],INDICES=dividends$year,FUN=sum,na.rm=TRUE)
}
names(div_output) <- names(dividends)[1:4]

使用一个简单的循环,我们只需遍历每一列并应用 by() 函数。变量是列,索引是年份,我们只使用 sum 函数。我在 na.rm=TRUE 上进行标记,以便您获得实际数据而不是 NA。

print(div_output)

     barc_ln barn_se bas_gy bats_ln
1999    0.49    0.84   0.35       0
2000    0.00    0.00   0.40       0
2001    0.85    0.00   0.15       0

这就是我得到的输出。

于 2012-06-25T16:30:36.503 回答