仅使用特定公式替换xts对象列中的NA值

问题描述 投票:0回答:1

我想用公式Beta * Exposure * Index return替换xts对象中的NA值。我的xts对象是在下面创建的Position_SimPnl:

library(xts)    
df1 <- data.frame(Google = c(NA, NA, NA, NA, 500, 600, 700, 800),
                    Apple = c(10, 20,30,40,50,60,70,80),
                    Audi = c(1,2,3,4,5,6,7,8),
                    BMW = c(NA, NA, NA, NA, NA, 6000,7000,8000),
                    AENA = c(50,51,52,53,54,55,56,57))

Position_SimPnl <- xts(df1, order.by = Sys.Date() - 1:8)

对于Beta,有一个特定的数据框:

Beta_table <- data.frame (AENA = c(0.3,0.5,0.6), Apple = c(0.2,0.5,0.8), Google = c(0.1,0.3,0.5), Audi = c(0.4,0.6,0.7), AXP = c(0.5,0.7, 0.9), BMW = c(0.3,0.4, 0.5))
rownames(Beta_table) <- c(".SPX", ".FTSE", ".STOXX")

对于曝光,还有另一个数据框:

Base <- data.frame (RIC = c("AENA","BMW","Apple","Audi","Google"), Exposure = c(100,200,300,400,500))

对于索引返回,有一个xts对象(Index_FX_Returns):

    df2 <- data.frame(.SPX = c(0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08),
                    .FTSE = c(0.5, 0.4,0.3,0.2,0.3,0.4,0.3,0.4),
                    .STOXX = c(0.15,0.25,0.35,0.3,0.45,0.55,0.65,0.5))

Index_FX_Returns <- xts(df2,order.by = Sys.Date() - 1:8)

也有一个将RIC与索引链接的数据框:

RIC_Curr_Ind <- data.frame(RIC = c("AENA", "Apple", "Google", "Audi", "BMW"), Currency = c("EUR.","USD.","USD.","EUR.","EUR."), Index = c(".STOXX",".SPX",".SPX",".FTSE",".FTSE"))

我想要的是对于Position_SimPnl中NA值的特定位置,它应该查看列名并从RIC_Curr_Ind数据框中获取相应的索引名,然后通过匹配列名(NA的列名)从Beta_table中查找beta值和行名(从NA的列名派生的索引名)。然后再次通过将Position_SimPnl中的列名与“ Base”数据帧中的RIC列进行匹配,将提取相应的曝光值。然后通过将Position_SimPnl中的列名与RIC_Curr_Ind数据帧中的RIC列进行匹配,它将获得相应的索引名,并从该索引名中查找xts对象Index_FX_Returns的列名,并获得与该日期相同的日期的相应返回值。 NA值。

获得Beta,Exposure和Index返回值后,我希望将NA值替换为公式:Beta * Exposure * Index return。我也只希望替换Position_SimPnl中的NA值。其他值应保持不变。我使用以下公式替换了NA值:

do.call(merge, lapply(Position_SimPnl, function(y) {if(is.na(y)){y = (Beta_table[match(RIC_Curr_Ind$Index[match(colnames(y),RIC_Curr_Ind$RIC)],rownames(Beta_table)), match(colnames(y),colnames(Beta_table))]) * (Base$Exposure[match(colnames(y), Base$RIC)]) * (Index_FX_Returns[,RIC_Curr_Ind$Index[match(colnames(y),RIC_Curr_Ind$RIC)]])} else{y}}))

但是,在输出中,如果特定列包含NA,它将替换该列中的所有值(包括以前不是NA的值)。我也收到多个警告消息,例如“如果(is.na(y)){...:条件的长度> 1,并且仅使用第一个元素”。我认为因此,包括非NA值在内的所有列值都在发生变化。任何人都可以建议如何用上述公式有效替换这些NA值,并使其他值保持不变。任何帮助,将不胜感激

r lapply na xts
1个回答
0
投票

因为您需要组合所有数据集才能获得公式Beta * Exposure * Index,所以请考虑构建一个包含所有必需组件的主数据框。但是,您面临两个挑战:

  • 不同的数据类型(xts对象和数据框)
  • 不同的数据格式(widelong格式)

[为了进行正确的合并和计算,请考虑将所有数据分量转换为数据帧,然后将其重塑为长格式(即BaseRIC_Curr_Ind除外)。然后,merge并使用ifelse进行计算以填充NA值。当然,最后,您将不得不重新调整为宽宽并转换回XTS。

Reshape

# USER-DEFINED METHOD GIVEN THE MULTIPLE CALLS 
proc_transpose <- function(df, col_pick, val_col, time_col) {
  reshape(df, 
          varying = names(df)[col_pick],
          times = names(df)[col_pick], ids = NULL,
          v.names = val_col, timevar = time_col,
          new.row.names = 1:1E4, direction = "long")
}

# POSITIONS
Position_SimPnl_wide_df <- data.frame(date = index(Position_SimPnl), 
                                      coredata(Position_SimPnl))

Position_SimPnl_long_df <- proc_transpose(Position_SimPnl_wide_df, col_pick = -1,
                                          val_col = "Position", time_col = "RIC")

# BETA
Beta_table_long_df <- proc_transpose(transform(Beta_table, Index = row.names(Beta_table)),
                                     col_pick = 1:ncol(Beta_table),
                                     val_col = "Beta", time_col = "RIC")

# INDEX
Index_FX_Returns_wide_df <- data.frame(date = index(Index_FX_Returns),
                                  coredata(Index_FX_Returns))

Index_FX_Returns_long_df <- proc_transpose(Index_FX_Returns_wide_df, col = -1,
                                           val_col = "Index_value", time_col = "Index")

合并

# CHAIN MERGE
master_df <- Reduce(function(...) merge(..., by="RIC"), 
                    list(Position_SimPnl_long_df, 
                         Beta_table_long_df, 
                         Base)
                    )

# ADDITIONAL MERGES (NOT INCLUDED IN ABOVE CHAIN DUE TO DIFFERENT by)
master_df <- merge(master_df,
                   Index_FX_Returns_long_df, by=c("Index", "date"))

master_df <- merge(master_df,
                   RIC_Curr_Ind, by=c("Index", "RIC"))

计算

# FORMULA: Beta * Exposure * Index 
master_df$Position <- with(master_df, ifelse(is.na(Position),  
                                             Beta * Exposure * Index_value, 
                                             Position))

最终制剂

# RE-ORDER ROWS AND SUBSET COLS
master_df <- data.frame(with(master_df, master_df[order(RIC, date), 
                                                  c("date", "RIC", "Position")]),
                        row.names = NULL)

# RESHAPE WIDE (REVERSE OF ABOVE)
Position_SimPnl_new <- setNames(reshape(master_df, idvar = "date",
                                        v.names = "Position", timevar = "RIC",
                                        direction = "wide"),
                                c("date", unique(master_df$RIC)))

# CONVERT TO XTS
Position_SimPnl_new <- xts(transform(Position_SimPnl_new, date = NULL),
                           order.by = Position_SimPnl_new$date)

Position_SimPnl_new 

#            AENA Apple Audi  BMW Google
# 2019-11-27   58    80    8 8000  800.0
# 2019-11-28   57    70    7 7000  700.0
# 2019-11-29   56    60    6 6000  600.0
# 2019-11-30   55    50    5   24  500.0
# 2019-12-01   54    40    4   16    2.0
# 2019-12-02   53    30    3   24    1.5
# 2019-12-03   52    20    2   32    1.0
# 2019-12-04   51    10    1   40    0.5
© www.soinside.com 2019 - 2024. All rights reserved.