Sanjeev Agarwal
Sanjeev Agarwal

Reputation: 23

Unable to format date in a dataframe

I have some raw data in a dataframe ("datafile"), which I have processed and stored its output in a new dataframe ("result"). The output dataframe has three columns - trade, trade.date and trade.price. For some reason, "trade.date" shows R's internal date numbers, as opposed to dates in a standard format ("yyyy-mm-dd"). None of the solutions to similar issues that I have read about seem to work. What am I missing?

# READ RAW DATA   
datafile<-data.frame(date=index(final2), coredata(final2),stringsAsFactors=FALSE)
datafile<-datafile[1:5,]
# SHOW  DATA
datafile

#date   close   Worst  Stress Support FairValue Resistance BestCase  Bubble
#1 2001-01-02 1015.79 740.293 1024.67 1658.02   2366.08    2571.79  2814.98 3664.04
#2 2001-01-03 1043.74 741.349 1024.84 1658.16   2366.32    2571.83  2814.93 3663.55
#3 2001-01-04 1034.66 741.772 1024.64 1657.72   2366.02    2571.69  2814.82 3663.39
#4 2001-01-05 1046.99 741.849 1024.57 1657.84   2365.97    2571.69  2814.76 3663.94
#5 2001-01-08 1033.98 741.686 1024.55 1657.98   2365.92    2571.82  2814.93 3663.38

# CREATE A DATAFRAME FOR HOLDING PROCESSED DATA
result<-data.frame(trade=NA, trade.date=NA, trade.price=NA)


# PROCESS DATA
i<-1
rows<-nrow(datafile)
while (i < rows) {
  if (datafile[i,"close"] < datafile[i,"Resistance"]) {
  trade <- "long"
  trade.date <- datafile[i,"date"]
  trade.price <- datafile[i,"close"]
  result[i,]<-c(trade,as.Date(trade.date),trade.price)
  i=i+1
  }
}

result

trade trade.date trade.price
1  long      11324     1015.79
2  long      11325     1043.74
3  long      11326     1034.66
4  long      11327     1046.99

Upvotes: 2

Views: 135

Answers (2)

eipi10
eipi10

Reputation: 93761

In your code, c(trade, as.Date(trade.date), trade.price) creates a vector with three values. All elements of a vector have to be of the same class, so R coerces trade.date back to numeric. You can avoid this by using cbind ("column bind") instead of c. I've also streamlined the code a bit.

# PROCESS DATA
for (i in 1:nrow(datafile)) {
  if (datafile[i,"close"] < datafile[i,"Resistance"]) {

    result[i,] <- cbind("long", datafile[i, "date"], datafile[i, "close"])

  }
}

result

  trade trade.date trade.price
1  long 2001-01-02     1015.79
2  long 2001-01-03     1043.74
3  long 2001-01-04     1034.66
4  long 2001-01-05     1046.99
5  long 2001-01-08     1033.98

You can avoid the loop entirely as follows:

result = data.frame(trade="long", 
                    datafile[datafile$close < datafile$Resistance, c("date","close")])

Here's another option, using the dplyr package, that will be very fast if you have a large data frame (as will @agstudy's data.table version):

library(dplyr)

result = datafile %>% 
  filter(close < Resistance) %>%
  mutate(trade="long") %>%
  select(trade, date, close)

Upvotes: 4

agstudy
agstudy

Reputation: 121568

No need to use a while-loop here. Here a data.table solution.

library(data.table)
setDT(datafile)[close<Resistance,list(trade="long",date,close)]
#     trade       date close
# 1:  long 2001-01-02  1016
# 2:  long 2001-01-03  1044
# 3:  long 2001-01-04  1035
# 4:  long 2001-01-05  1047
# 5:  long 2001-01-08  1034

PS: I am just using data.table for sugar-syntax feature.

Upvotes: 3

Related Questions