donPablo
donPablo

Reputation: 1959

R Add column into data.frame, that is in list of data.frames

1A--How can I add another column to aPrices, named topPct? which is the calculation of any given day's Close divided by the value topClose.

1B--Or is extending aPrices from [170 x 7] to [170 x 8] the wrong thing to do? Should column topPct (et.al.) be created into a new of df-s named aPercents[170 x 1+]?

2--What is the effect of these 2 alternatives on later charting of all the values? That is, having only aPrices [8+ columns] or having both aPrices [7] and aPercents[1+ cols]?

To create the data, use

#1A. Create function for prices
myget_stock_prices <- 
function(ticker, return_format = "tibble", ...) {
        # myget_stock_prices
        stock_prices_xts <- getSymbols(Symbols = ticker, auto.assign = FALSE, ...)
        # name the columns
        names(stock_prices_xts) <- c("Open", "High", "Low", "Close", "Volume", "Adjusted")
        # Return in xts format if tibble is not specified
        if (return_format == "tibble") {
            stock_prices <- as_tibble(data.frame(Date=index(stock_prices_xts), coredata(stock_prices_xts))) 
        } else {
            stock_prices <- stock_prices_xts
        }
        stock_prices
    }



#2A. Get Stock Prices
library(dplyr)  # for %>%  and mutate
library(purrr)  # for  map
library(tibble)  # for as.tibble
library(lubridate)  # for ymd functions
library(quantmod)  # for getSymbols functions

myuSYMB <- as.data.frame(c("IBM", "MMM"))
colnames(myuSYMB) <- c("symbol")
myuprices <- myuSYMB  %>%
    mutate (
    aPrices = map(symbol, 
                 function(.x) myget_stock_prices(.x, return_format = "tibble",
                     from = "2019-10-01" ) 
                 )
           )



#3A. mutate for TOP 
rm(myuptop)
myuptop <- myuprices %>%   mutate (
  topNdx  =         map_dbl(aPrices, function(.x)            (which.max(.x$Close) )  ),
  topDate = as.Date(map_dbl(aPrices, function(.x)  {(.x$Date [which.max(.x$Close)])} ) ), 
  topClose =        map_dbl(aPrices, function(.x)  {(.x$Close[which.max(.x$Close)])} ) 
)  
glimpse(myuptop)


#4X. cleanup, at a later time
#rm(myget_stock_prices, myuSYMB, myuprices, myuptop)

> glimpse(myuptop)
Rows: 2
Columns: 5
$ symbol   <chr> "IBM", "MMM"
$ aPrices  <list> [<tbl_df[170 x 7]>, <tbl_df[170 x 7]>]
$ topNdx   <dbl> 89, 73
$ topDate  <date> 2020-02-06, 2020-01-14
$ topClose <dbl> 156.76, 181.37

The symbol column could have more symbols-- DJ60 or S&P500 ... . The table aPrices has the standard columns-- Date, Open, High, Low, Close, Volumne, Adjusted

Expected results for symbol IBM View(myuptop$aPrices[[1]]) --

row Date            Close   topPct
87  2/4/2020    149.11   95.12%
88  2/5/2020    156.33   99.73%
89  2/6/2020    156.76  100.00%
90  2/7/2020    153.41   97.86%
91  2/10/2020   154.43   98.51%
92  2/11/2020   153.48   97.91%
93  2/12/2020   155.31   99.08%

This is being run on R version 4.0.0 (2020-04-24) nickname Arbor Day
I have tried these two, but get errors

hp50uppct <- hp50uptop %>% mutate (
    aPrices$topPct = map_dbl(aPrices, function(.x) {(.x$Close / hp50uptop$topClose)} )  )

Error: unexpected '=' and Error: unexpected ')'

hp50uppct <- hp50uptop %>% Map(cbind, aPrices, topPct = (Close / hp50uptop$topClose) )

Error in get(as.character(FUN), mode = "function", envir = envir) : object '.' of mode 'function' was not found

Upvotes: 1

Views: 169

Answers (2)

akrun
akrun

Reputation: 887118

We can use base R

myuptop$aPrices <- Map(function(x, y) transform(x, topPct = Close/y * 100), 
                    myuptop$aPrices, myuptop$topClose)

Upvotes: 1

Ronak Shah
Ronak Shah

Reputation: 388982

You can use :

library(dplyr)
library(purrr)

hp50uppct <- myuptop %>% 
                mutate(aPrices = map2(aPrices, topClose,
                               ~{.x$topPct = .x$Close/.y * 100;.x})) 

glimpse(hp50uppct)
#Rows: 2
#Columns: 5
#$ symbol   <chr> "IBM", "MMM"
#$ aPrices  <list> [<tbl_df[171 x 8]>, <tbl_df[171 x 8]>]
#$ topNdx   <dbl> 89, 73
#$ topDate  <date> 2020-02-06, 2020-01-14
#$ topClose <dbl> 157, 181

Or using base R :

myuptop$aPrices <- Map(function(x, y) {x$topPct = x$Close/y * 100;x}, 
                        myuptop$aPrices, myuptop$topClose)

Upvotes: 2

Related Questions