我有一个庞大的不平衡数据集(约2000支股票),由股票的收益数据组成,现在我想重新排列收益数据,因此所有结果都在同一日期结束。
我的数据看起来像这样:
Date RF STOCK-A STOCK-B STOCK-C STOCK-D
1990-11-30 0,03 0,20 0,30 -0,40 0,90
1990-12-31 0,10 0,30 0,30 -0,40 0,34
1991-01-31 0,12 0,90 0,30 -0,60 0,78
1991-02-28 0,03 0,12 0,30 NA 0,50
1991-03-31 0,04 0,14 0,30 NA 0,12
1991-04-30 0,05 0,18 0,30 NA 0,11
1991-05-31 0,03 0,00 NA NA NA
1991-06-30 0,00 0,20 NA NA NA
我的问题是,我希望所有以1991-06-30结尾的股票收益并在早期日期填写NA,所以它看起来像这样:
Date RF STOCK-A STOCK-B STOCK-C STOCK-D
1990-11-30 0,03 0,20 NA - NA NA
1990-12-31 0,10 0,30 NA NA NA
1991-01-31 0,12 0,90 0,30 NA 0,90
1991-02-28 0,03 0,12 0,30 NA 0,34
1991-03-31 0,04 0,14 0,30 NA 0,78
1991-04-30 0,05 0,18 0,30 -0,40 0,50
1991-05-31 0,03 0,00 0,30 -0,40 0,12
1991-06-30 0,00 0,20 0,30 -0,60 0,11
我尝试过使用lag函数,如下所示:
data2 <- if (any(is.na(data$STOCK-B))==TRUE){
lag(data$STOCK-B, k= -sum(is.na(data$STOCK-B)))
}else {
any(is.na(data$STOCK-B)==FALSE)
lag(data$STOCK-B, k=0)
}
我的想法是在for循环中实现它,但是它不起作用,只是返回一个原子向量。
我使用DataCombine包找到了另一种方法:
Data1 <- slide(data, Var = "data$STOCK-B", slideBy = -sum(is.na(data$STOCK-
B)))
它根据需要将数据向下移动,但向数据集输入新变量。当然,我可以使用该方法,然后将新变量提取到新数据集中,但这如何使它更有效?
提前谢谢!!
答案 0 :(得分:2)
对于每一列,将NA与非NA连接起来:
moveNA <- function(x) c(Filter(is.na, x), na.omit(x))
replace(data, -1, lapply(data[-1], moveNA))
给予:
Date RF STOCK.A STOCK.B STOCK.C STOCK.D
1 1990-11-30 0.03 0.20 NA NA NA
2 1990-12-31 0.10 0.30 NA NA NA
3 1991-01-31 0.12 0.90 0.3 NA 0.90
4 1991-02-28 0.03 0.12 0.3 NA 0.34
5 1991-03-31 0.04 0.14 0.3 NA 0.78
6 1991-04-30 0.05 0.18 0.3 -0.4 0.50
7 1991-05-31 0.03 0.00 0.3 -0.4 0.12
8 1991-06-30 0.00 0.20 0.3 -0.6 0.11
另一种甚至更短的moveNA
是:
moveNA <- function(x) x[order(!is.na(x))]
使用的可复制形式的输入data
是:
data <-
structure(list(Date = structure(1:8, .Label = c("1990-11-30",
"1990-12-31", "1991-01-31", "1991-02-28", "1991-03-31", "1991-04-30",
"1991-05-31", "1991-06-30"), class = "factor"), RF = c(0.03,
0.1, 0.12, 0.03, 0.04, 0.05, 0.03, 0), STOCK.A = c(0.2, 0.3,
0.9, 0.12, 0.14, 0.18, 0, 0.2), STOCK.B = c(0.3, 0.3, 0.3, 0.3,
0.3, 0.3, NA, NA), STOCK.C = c(-0.4, -0.4, -0.6, NA, NA, NA,
NA, NA), STOCK.D = c(0.9, 0.34, 0.78, 0.5, 0.12, 0.11, NA, NA
)), class = "data.frame", row.names = c(NA, -8L))
答案 1 :(得分:1)
我们可以定义一个有助于排序的函数,然后使用mutate_at
包中的dplyr
对每一列进行排序。
library(dplyr)
sort_fun <- function(x){
x_NA <- x[is.na(x)]
x_non_NA <- x[!is.na(x)]
x <- c(x_NA, x_non_NA)
return(x)
}
dat2 <- dat %>%
mutate_at(vars(-Date), funs(sort_fun(.)))
dat2
# Date RF STOCK.A STOCK.B STOCK.C STOCK.D
# 1 1990-11-30 0,03 0,20 <NA> <NA> <NA>
# 2 1990-12-31 0,10 0,30 <NA> <NA> <NA>
# 3 1991-01-31 0,12 0,90 0,30 <NA> 0,90
# 4 1991-02-28 0,03 0,12 0,30 <NA> 0,34
# 5 1991-03-31 0,04 0,14 0,30 <NA> 0,78
# 6 1991-04-30 0,05 0,18 0,30 -0,40 0,50
# 7 1991-05-31 0,03 0,00 0,30 -0,40 0,12
# 8 1991-06-30 0,00 0,20 0,30 -0,60 0,11
数据
dat <- read.table(text = "Date RF STOCK-A STOCK-B STOCK-C STOCK-D
1990-11-30 0,03 0,20 0,30 -0,40 0,90
1990-12-31 0,10 0,30 0,30 -0,40 0,34
1991-01-31 0,12 0,90 0,30 -0,60 0,78
1991-02-28 0,03 0,12 0,30 NA 0,50
1991-03-31 0,04 0,14 0,30 NA 0,12
1991-04-30 0,05 0,18 0,30 NA 0,11
1991-05-31 0,03 0,00 NA NA NA
1991-06-30 0,00 0,20 NA NA NA",
header = TRUE, stringsAsFactors = FALSE)
答案 2 :(得分:0)
我将使用apply
函数:
apply(data,2,function(x) as.numeric(x[order(!is.na(x))]))
数据
data <-structure(list(Date = structure(1:8, .Label = c("1990-11-30",
"1990-12-31", "1991-01-31", "1991-02-28", "1991-03-31", "1991-04-30",
"1991-05-31", "1991-06-30"), class = "factor"), RF = c(0.03,
0.1, 0.12, 0.03, 0.04, 0.05, 0.03, 0), STOCK.A = c(0.2, 0.3,
0.9, 0.12, 0.14, 0.18, 0, 0.2), STOCK.B = c(0.3, 0.3, 0.3, 0.3,
0.3, 0.3, NA, NA), STOCK.C = c(-0.4, -0.4, -0.6, NA, NA, NA,
NA, NA), STOCK.D = c(0.9, 0.34, 0.78, 0.5, 0.12, 0.11, NA, NA
)), class = "data.frame", row.names = c(NA, -8L))