Умножьте столбцы из разных фреймов данных, если даты совпадают - PullRequest
0 голосов
/ 14 апреля 2020

У меня есть два следующих фрейма данных:

df1 <- data.frame(Category = c("A", "A", "A", "B", "B", "B", "C", "C", "C"),
                  Date = c(2001, 2002, 2003, 2001, 2002, 2003, 2001, 2002, 2003),
                  Beta1 = c(1, 3, 4, 4, 5, 3, 5, 3, 1),
                  Beta2 = c(2, 4, 6, 1, 1, 2, 5, 4, 2))

df2 <- data.frame(Date = c(2001, 2002, 2003),
                   Column1 = c(10, 20, 30),
                   Column2 = c(40, 50, 60)) 

Скажем, я назначаю категорию A для Column1 и категорию C для Column2. Я хочу умножить значение строки из Column1 на число бета-строк из категории A, , если даты соответствуют Точно так же я хочу умножить значение строки из Column2 на число бета-версий строки из категории C, , если даты соответствуют .

Совпадение между категорией и столбцом - по моему выбору. Я думаю, что это не проблема, потому что у меня относительно мало столбцов.

Желательно, чтобы вывод выглядел следующим образом:

results <- data.frame(Date = c(2001, 2002, 2003),
                      Column1_categoryA_beta1 = c(10, 60, 120),
                      Column1_categoryA_beta2 = c(20, 80, 180),
                      Column2_categoryC_beta1 = c(200, 150, 60),
                      Column2_categoryC_beta2 = c(200, 200, 120))

Любая помощь в том, как мне лучше всего подойти к этой проблеме, очень ценится!

Ответы [ 3 ]

1 голос
/ 14 апреля 2020

С некоторыми обработками данных с использованием tidyr и dplyr это может быть достигнуто следующим образом:

df1 <- data.frame(Category = c("A", "A", "A", "B", "B", "B", "C", "C", "C"),
                  Date = c(2001, 2002, 2003, 2001, 2002, 2003, 2001, 2002, 2003),
                  Beta1 = c(1, 3, 4, 4, 5, 3, 5, 3, 1),
                  Beta2 = c(2, 4, 6, 1, 1, 2, 5, 4, 2))

df2 <- data.frame(Date = c(2001, 2002, 2003),
                  Column1 = c(10, 20, 30),
                  Column2 = c(40, 50, 60))


library(dplyr)
library(tidyr)

df2_long <- df2 %>% 
  pivot_longer(-Date, names_to = "Column", values_to = "Value") %>% 
  mutate(Category = ifelse(Column == "Column1", "A", "C"))

df2_long %>% 
  left_join(df1) %>% 
  mutate(Beta1 = Value * Beta1,
         Beta2 = Value * Beta2) %>% 
  select(Date, Category, Column, Beta1, Beta2) %>% 
  pivot_wider(id_cols = Date, names_from = c("Column", "Category"), values_from = c("Beta1", "Beta2"))
#> Joining, by = c("Date", "Category")
#> Warning: Column `Category` joining character vector and factor, coercing into
#> character vector
#> # A tibble: 3 x 5
#>    Date Beta1_Column1_A Beta1_Column2_C Beta2_Column1_A Beta2_Column2_C
#>   <dbl>           <dbl>           <dbl>           <dbl>           <dbl>
#> 1  2001              10             200              20             200
#> 2  2002              60             150              80             200
#> 3  2003             120              60             180             120

Создано в 2020-04-14 с помощью пакета Представить (v0.3.0)

0 голосов
/ 14 апреля 2020

Это может быть начало. В результирующем data.table есть вся необходимая информация только в другом формате.

df3 <- merge(df1, df2)
df3$b1 <- ifelse(df3$Category=="A", df3$Beta1*df3$Column1, ifelse(df3$Category=="C", df3$Beta1*df3$Column2, NA))
df3$b2 <- ifelse(df3$Category=="A", df3$Beta2*df3$Column1, ifelse(df3$Category=="C", df3$Beta2*df3$Column2, NA))

# Date Category Beta1 Beta2 Column1 Column2  b1  b2
# 1 2001        A     1     2      10      40  10  20
# 2 2001        C     5     5      10      40 200 200
# 3 2001        B     4     1      10      40  NA  NA
# 4 2002        A     3     4      20      50  60  80
# 5 2002        B     5     1      20      50  NA  NA
# 6 2002        C     3     4      20      50 150 200
# 7 2003        B     3     2      30      60  NA  NA
# 8 2003        A     4     6      30      60 120 180
# 9 2003        C     1     2      30      60  60 120
0 голосов
/ 14 апреля 2020

Один из способов получить это при сохранении переменной Category в конечном кадре данных заключается в следующем:

df3 <- left_join(df1, df2, by="Date")
df4 <- df3 %>%
  group_by(Date, Category) %>%
  mutate(Col1Bet1 = Column1 * Beta1, Col1Bet2 = Column1 * Beta2, Col2Bet1 = Column2 * Beta1, Col2Bet2 = Column2 * Beta2)

, что дает следующее:

# A tibble: 9 x 10
# Groups:   Date, Category [9]
  Category  Date Beta1 Beta2 Column1 Column2 Col1Bet1 Col1Bet2 Col2Bet1 Col2Bet2
  <fct>    <dbl> <dbl> <dbl>   <dbl>   <dbl>    <dbl>    <dbl>    <dbl>    <dbl>
1 A         2001     1     2      10      40       10       20       40       80
2 A         2002     3     4      20      50       60       80      150      200
3 A         2003     4     6      30      60      120      180      240      360
4 B         2001     4     1      10      40       40       10      160       40
5 B         2002     5     1      20      50      100       20      250       50
6 B         2003     3     2      30      60       90       60      180      120
7 C         2001     5     5      10      40       50       50      200      200
8 C         2002     3     4      20      50       60       80      150      200
9 C         2003     1     2      30      60       30       60       60      120
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...