Вызов API для каждой строки фрейма данных в R

У меня есть один столбец в фрейме данных, который состоит из тикерных кодов, таких как AAPL (для акций Apple), TWTR (для Twitter) и многих других. Я пытаюсь создать новый столбец, в котором он будет возвращать количество акций для каждого кода тикера, рассчитанного на основе данных API акций.

Но когда я запустил приведенный ниже код, новый столбец «Количество запасов» возвращал NA для каждой строки. У кого-нибудь есть решение этой проблемы?

library(Quandl)

portfolio <- data.frame(Code=c("AAPL", "TWTR", "MSFT"),
                startingPeriod=c("2015-01-01", "2015-01-01", "2015-01-01"),
                Investment=c("5000", "10000", "15000"), 
                stringsAsFactors=FALSE)


numberofStock <- function(pf) {

API <- Quandl(paste0("WIKI/", pf$Code), type = "raw", 
            start_date = pf$startingPeriod, end_date=Sys.Date())

pf["StockQuantity"] <- floor(pf$Investment_01 / tail(API$Open,1))

return(pf)
}


numberofStock(portfolio) 

person Fxs7576    schedule 30.04.2016    source источник


Ответы (2)


Вот начало.

library(dplyr)

company.initial = 
  portfolio %>%
  mutate(Investment = as.numeric(Investment) ) %>%
  group_by(Code) %>%
  summarize(start_date = min(startingPeriod),
            total_investment = sum(Investment) )

company__date = 
  company.initial %>%
  group_by(Code) %>%
  do(with(.,
     Quandl(paste0("WIKI/", Code), 
            type = "raw",
            start_date = start_date, 
            end_date = Sys.Date() ) ) )

company = 
  company__date %>%
  group_by(Code) %>%
  summarize(last_open = last(Open)) %>%
  left_join(company.initial) %>%
  mutate(StockQuantity = total_investment / last_open)
person bramtayl    schedule 30.04.2016
comment
Большое тебе спасибо. Ваш код работает, и он намного проще и аккуратнее. - person Fxs7576; 10.05.2016
comment
Кстати, не могли бы вы объяснить, почему для этой цели мы должны использовать обе функции «Сделать» и «С»? - person Fxs7576; 11.05.2016
comment
Когда код внутри цикла do оценивается, он оценивается с помощью . как часть фрейма данных. Чтобы получить столбцы в чанке, вы можете либо выполнить .$Code, либо оценить код в среде . - person bramtayl; 11.05.2016

Вы можете начать с преобразования portfolio$startingPeriod в тип данных Date с помощью as.Date. Кроме того, вы передаете два вектора, portfolio$Code и portfolio$startingPeriod, функции Quandl(). Вы можете попробовать использовать функцию lapply() для повторения каждого значения этих двух функций.

РЕДАКТИРОВАТЬ: вам также нужно будет преобразовать portfolio$Investment в numeric, используя as.numeric(). Вот как должен выглядеть код:

portfolio <- data.frame(Code=c("AAPL", "TWTR", "MSFT"),
                        startingPeriod=as.Date(c("2015-01-01", "2015-01-01", "2015-01-01")),
                        Investment=as.numeric(c("5000", "10000", "15000")), 
                        stringsAsFactors=FALSE)


numberofStock <- function(pf) {lapply(seq_along(nrow(portfolio)), function(x){
    API <- Quandl(paste0("WIKI/", pf$Code[x]), type = "raw", 
                  start_date = pf$startingPeriod[x], end_date=Sys.Date())

    pf["StockQuantity"] <- floor(pf$Investment[x] / tail(API$Open,1))

    return(pf)
    })
}

numberofStock(portfolio)
person seasmith    schedule 30.04.2016
comment
Спасибо. Я запустил ваш код, и он успешно удалил NA из вывода. Однако я заметил, что новый столбец «Количество запасов» возвращает то же значение 44. Результат должен быть 44, 275 и 321 соответственно. В чем может быть проблема? - person Fxs7576; 01.05.2016
comment
@ Fxs7576 Попробуйте заменить seq_along(nrow(portfolio)) на seq(1:nrow(pf)), а return(pf) на return(pf[x,]. Первое изменение позволит выполнять итерацию по всем строкам (поскольку исходная итерация выполнялась только один раз). Второе изменение вернет конкретную строку, к которой применен цикл. Я думаю, вы можете использовать что-то вроде plyr::ldply() для объединения всех строк в один фрейм данных. - person seasmith; 01.05.2016
comment
Работает как часы. В дополнение к вашему коду я использовал y ‹- do.call(rbind.data.frame, lapply(seq(1:nrow(pf)), function(x) {...}))return(y)} для объединить все строки в один фрейм данных. Я очень ценю вашу помощь. - person Fxs7576; 03.05.2016