Может ли R выполнять эквивалент HLOOKUP, вложенного в VLOOKUP? - PullRequest
2 голосов
/ 19 июня 2020

Я пытаюсь (безуспешно) сделать эквивалент HLOOKUP, вложенного в VLOOKUP в Excel, используя R Studio.

Вот ситуация.

У меня две таблицы. Таблица 1 содержит исторические цены на акции, где каждый столбец представляет название тикера, а каждая строка представляет конкретную дату. Таблица 1 содержит цену акций на конец периода для каждого тикера на каждую дату.

Предположим, что таблица 1 выглядит следующим образом:

 |----------------------------|
 |   Date   |MSFT | AMZN |EPD | 
 |----------------------------|
 | 6/1/2020 | 196 | 2600 | 19 |
 | 5/1/2020 | 186 | 2200 | 20 |
 | 4/1/2020 | 176 | 2000 | 15 |
 | 3/1/2020 | 166 | 1800 | 14 |
 | 2/1/2020 | 170 | 2200 | 18 |
 | 1/1/2020 | 180 | 2300 | 17 |
 |----------------------------|

В таблице 2 есть список символов тикера, а также две даты и заполнители для цены акций на каждую дату. Date1 всегда является более ранней датой, чем Date2, и каждая из Date1 и Date2 соответствует дате в таблице 1. Обратите внимание, что Date1 и Date2 различаются для каждой строки таблицы 2.

Моя цель состоит в том, чтобы извлечь применимые PriceOnDate1 и PriceOnDate2 в таблице 2 аналогично функциям ВПР / ГПР в Excel. (Я не могу использовать Excel в дальнейшем, так как файл слишком велик для Excel). Затем я могу рассчитать доходность для каждой строки по следующей формуле: (Date2 - Date1) / Date1

Предположим, я хочу, чтобы таблица 2 выглядела так, но я не могу получить данные о ценах для PriceOnDate1 и PriceOnDate2:

|-----------------------------------------------------------|
| Ticker | Date1    | Date2    |PriceOnDate1 |PriceOnDate2  |
|-----------------------------------------------------------|
| MSFT   | 1/1/2020 | 4/1/2020 | _________   | ________     | 
| MSFT   | 2/1/2020 | 6/1/2020 | _________   | ________     |   
| AMZN   | 5/1/2020 | 6/1/2020 | _________   | ________     |
| EPD    | 1/1/2020 | 3/1/2020 | _________   | ________     |   
| EPD    | 1/1/2020 | 4/1/2020 | _________   | ________     |
|-----------------------------------------------------------|

Мой вопрос заключается в том, есть ли способ использовать R для извлечения в Таблицу 2 данных о ценах закрытия из Таблицы 1 для каждой Date1 и Date2 в каждой строке Таблицы 2. Например, в первой строке Таблицы 2 в идеале R-код должен вводить 180 для PriceOnDate1 и 176 для PriceOnDate2.

Я пробовал искать ответы, но не могу создать решение, которое позволило бы мне сделать это в R Studio. Может ли кто-нибудь помочь мне с решением? Я очень ценю ваше время. СПАСИБО !!

Ответы [ 3 ]

0 голосов
/ 19 июня 2020

Работа в чем-то вроде R требует, чтобы вы немного иначе относились к данным. С таблицей 1, вероятно, легче всего работать в развернутом виде. Затем вы можете просто объединить тикер и дату, чтобы получить нужные значения.

Данные:

table_1 <- data.frame(Date = c("6/1/2020", "5/1/2020", "4/1/2020", "3/1/2020", 
                               "2/1/2020", "1/1/2020"),
                      MSFT = c(196, 186, 176, 166, 170, 180),
                      AMZN = c(2600, 2200, 2000, 1800, 2200, 2300),
                      EPD = c(19, 20, 15, 14, 18, 17))

# only created part of Table 2
table_2 <- data.frame(Ticker = c("MSFT", "AMZN"),
                      Date1 = c("1/1/2020", "5/1/2020"),
                      Date2 = c("4/1/2020", "6/1/2020"))

Решение:

Подход tidyverse здесь довольно прост.

library(dplyr)
library(tidyr)

Во-первых, увеличьте сводную таблицу 1.

table_1_long <- table_1 %>% 
  pivot_longer(-Date, names_to = "Ticker", values_to = "Price")

Затем укажите цены, которые вы хотите путем сопоставления даты и тикера.

table_2 %>% 
  left_join(table_1_long, by = c(Date1 = "Date", "Ticker")) %>% 
  left_join(table_1_long, by = c(Date2 = "Date", "Ticker")) %>% 
  rename(PriceOnDate1 = Price.x,
         PriceOnDate2 = Price.y)

#   Ticker    Date1    Date2 PriceOnDate1 PriceOnDate2
# 1   MSFT 1/1/2020 4/1/2020          180          176
# 2   AMZN 5/1/2020 6/1/2020         2200         2600
0 голосов
/ 19 июня 2020

Это можно сделать с помощью одного соединения, если оба фрейма данных имеют длинный формат, за которым следует pivot_wider, чтобы получить желаемую окончательную форму.

В приведенном ниже коде используются образцы данных @ Adam. Обратите внимание, что в данных выборки даты кодируются как факторы. Вы, вероятно, захотите, чтобы ваши даты были закодированы как класс Date в ваших реальных данных.

library(tidyverse)

table_2 %>% 
  pivot_longer(-Ticker, values_to="Date") %>% 
  left_join(
    table_1 %>% 
      pivot_longer(-Date, names_to="Ticker", values_to="Price")
  ) %>% 
  pivot_wider(names_from=name, values_from=c(Date, Price)) %>% 
  rename_all(~gsub("Date_", "", .))
  Ticker Date1    Date2    Price_Date1 Price_Date2
1 MSFT   1/1/2020 4/1/2020         180         176
2 AMZN   5/1/2020 6/1/2020        2200        2600
0 голосов
/ 19 июня 2020

Функция mapply сделает это здесь:

Допустим, ваша первая таблица хранится в data.frame с именем df, а вторая - в data.frame с именем df2

df2$PriceOnDate1 <- mapply(function(ticker, date){temp[[ticker]][df$Date == date]}, df2$Ticker, df2$Date1)
df2$PriceOnDate2 <- mapply(function(ticker, date){temp[[ticker]][df$Date == date]}, df2$Ticker, df2$Date2)

В этом коде Hlookup - это двойные скобки ([[), которые возвращают столбец с таким именем. ВПР - это одиночные скобки ([), которые возвращают значение в определенной позиции.

...