麻烦填充数据框&将数据移动到另一个数据框时重命名列

时间:2014-03-08 15:49:36

标签: r dataframe

我正在运行一个脚本,从雅虎财经下载股票价格,然后计算其价格变化的对数,前20天的标准差,将第i个价格乘以第i个标准差,然后除以当前的价格变化按前一天的价格变动或i-1。

我到处都是循环,这是第一个红旗,因为有更好的方法在R中做事。我很乐意尽可能使用矢量化操作。

我在R中定义一个空数据框以包含我想要的信息。我读到这是一个坏主意。我知道数据框有多大,因为我知道我要下载价格的符号数量。但是,当我初始化数据框时,它只是填充用0指定的行数并添加我想要的数据。通过在事实之后删除行来简单地修复它很容易,但我确信有一种更清洁的方式。

以下代码会产生错误:

 1: In `[<-.factor`(`*tmp*`, ri, value = "IBM") :
invalid factor level, NA generated.  

如果我在初始化SpikeData时将0更改为1,它将填充正常,但我需要删除在脚本的第3行到最后一行完成的空白第一行。

我遇到的第二个问题是SpikeRank数据框中的列名。我希望第一列标题为“符号”,接下来的5列为日期。但是,我似乎无法混合搭配。如果我将第一个col名称设置为“Symbol”,则日期将转换为序列号。使用此脚本,我将添加其他具有字符的列,因此我希望能够混合和匹配列名称中的日期和字符。

GetVol <- function(Window = 20, end=as.Date(Sys.time()), start = end-37){

library(tseries)
library(zoo)

SpikeRank = data.frame(stringsAsFactors=FALSE, Symbol=character(0),
SDInPriceTerms1=numeric(0), SDInPriceTerms2=numeric(0),
SDInPriceTerms3=numeric(0), SDInPriceTerms4=numeric(0), 
SDInPriceTerms5=numeric(0))

SymbolList <- c("AAPL", "IBM")

for (Symbol in SymbolList)
 {
ts <- get.hist.quote(instrument=Symbol, 
                   start, end, 
                   quote="Close", provider="yahoo", origin="1970-01-01",
                   compression="d", retclass="zoo")

df <- data.frame(ts)
df <- data.frame(Date=as.Date(rownames(df)), Close=df$Close)


df$PriorClose <- c(NA, head(df$Close, -1))
df$Return <- log(df$Close/df$PriorClose)

for (i in 1:length(df$Close))
{
  if(i < Window+1)  
  {
    df$stddev[i] = NA
    df$SDPrice[i] = NA
    df$CurrentSpike[i] = NA
  }

  else
  { 
    df$stddev[i] <- sd(df$Return[(i-Window+1):i], na.rm = TRUE)
    df$SDPrice[i] <- df$stddev[i] * df$Close[i]
    df$CurrentSpike[i] <- (df$Close[i] - df$PriorClose[i])/df$SDPrice[i-1]
  }

}#end for

df <- na.omit(df)
SpikeRank <-  rbind(SpikeRank, c(Symbol, df$CurrentSpike))

}#end for loop

SpikeRank <- SpikeRank[-1,]
colnames(SpikeRank) <- c(as.Date(1), df$Date)
print(SpikeRank)

SpikeRank的打印假设数据帧初始化为1s而不是0s,如下所示。行中的值都是正确的。我对计算没有任何问题。

1970-01-02         2014-03-03        2014-03-04        2014-03-05         2014-03-06
2       AAPL  0.268505943103897 0.613087867831883 0.195414096323545 -0.289567687725125
3        IBM -0.600147413085885  1.43686920161242 0.592564096496001  0.426680866502713
      2014-03-07
2 -0.055981998552076
3 0.0344269384370513

如果有帮助,这是IBM的df:

     Date  Close PriorClose        Return      stddev  SDPrice CurrentSpike
1  2014-01-30 177.36         NA            NA          NA       NA           NA
2  2014-01-31 176.68     177.36 -0.0038413786          NA       NA           NA
3  2014-02-03 172.90     176.68 -0.0216267940          NA       NA           NA
4  2014-02-04 172.84     172.90 -0.0003470816          NA       NA           NA
5  2014-02-05 174.24     172.84  0.0080673481          NA       NA           NA
6  2014-02-06 174.67     174.24  0.0024648203          NA       NA           NA
7  2014-02-07 177.25     174.67  0.0146626860          NA       NA           NA
8  2014-02-10 177.14     177.25 -0.0006207850          NA       NA           NA
9  2014-02-11 179.70     177.14  0.0143484134          NA       NA           NA
10 2014-02-12 180.24     179.70  0.0030005023          NA       NA           NA
11 2014-02-13 181.84     180.24  0.0088378834          NA       NA           NA
12 2014-02-14 183.69     181.84  0.0101223746          NA       NA           NA
13 2014-02-18 183.19     183.69 -0.0027256886          NA       NA           NA
14 2014-02-19 182.95     183.19 -0.0013109741          NA       NA           NA
15 2014-02-20 184.26     182.95  0.0071349122          NA       NA           NA
16 2014-02-21 182.79     184.26 -0.0080098508          NA       NA           NA
17 2014-02-24 183.45     182.79  0.0036041979          NA       NA           NA
18 2014-02-25 183.23     183.45 -0.0011999565          NA       NA           NA
19 2014-02-26 184.06     183.23  0.0045195971          NA       NA           NA
20 2014-02-27 185.27     184.06  0.0065524292          NA       NA           NA
21 2014-02-28 185.17     185.27 -0.0005398985 0.008188660 1.516294           NA
22 2014-03-03 184.26     185.17 -0.0049265184 0.008233949 1.517188  -0.60014741
23 2014-03-04 186.44     184.26  0.0117616678 0.006336123 1.181307   1.43686920
24 2014-03-05 187.14     186.44  0.0037475283 0.006261815 1.171836   0.59256410
25 2014-03-06 187.64     187.14  0.0026682336 0.006192074 1.161881   0.42668087
26 2014-03-07 187.68     187.64  0.0002131514 0.006236115 1.170394   0.03442694

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

首先,您的代码不会按照提供的方式运行。这是因为您无需定义startendWindow。所以我不得不从你的df推断IBM的那些值。 (顺便说一句:这可能就是为什么其他人都不愿意回应。对SO的期望是,如果你需要帮助,你将提供一个工作的例子)。

所以这是制作你所拥有的更短的方式。请注意使用rollapply(...)head(...)来避免内部循环,并使用do.call(rbind,lapply(...))来避免外部循环和SpikeRank的预分配。您坚持将日期作为列名创建了许多问题,因为在大多数创建数据框的函数中的默认行为是避免以数字开头的列名。

library(tseries)   # for get.hist.quote
library(zoo)       # for rollapply

start      <- "2014-01-30"
end        <- "2014-03-07"
Window     <- 20
SymbolList <- c("AAPL","IBM")

get.SpikeRank <- function(Symbol,start, end, Window) {
  ts <- get.hist.quote(instrument=Symbol, 
                       start, end, 
                       quote="Close", provider="yahoo", origin="1970-01-01",
                       compression="d", retclass="zoo")
  df <- data.frame(ts)
  df <- data.frame(Date=as.Date(rownames(df)), Close=df$Close)
  df$PriorClose   <- c(NA, head(df$Close, -1))
  df$Return       <- log(df$Close/df$PriorClose)
  df$stdev        <- c(rep(NA,Window),rollapply(df$Return[-1],width=Window,sd,na.rm=T))
  df$SDPrice      <- df$stdev * df$Close
  df$CurrentSpike <- (df$Close - df$PriorClose)/c(NA,head(df$SDPrice,-1))
  df              <- na.omit(df)
  row             <- df$CurrentSpike
  names(row)      <- df$Date
  return(row)
}
SpikeRank <- do.call(rbind,lapply(SymbolList,get.SpikeRank,start,end,Window))
SpikeRank <- data.frame(Symbol=SymbolList, SpikeRank)
colnames(SpikeRank)[-1] <- substring(colnames(SpikeRank)[-1],2)
print(SpikeRank)
#   Symbol 2014.03.03 2014.03.04 2014.03.05 2014.03.06  2014.03.07
# 1   AAPL  0.2685059  0.6130879  0.1954141 -0.2895677 -0.05598200
# 2    IBM -0.6001474  1.4368692  0.5925641  0.4266809  0.03442694
相关问题