Как повернуть пары комбинаций дата-вар с несовпадающими датами? - PullRequest
1 голос
/ 09 марта 2020

Вот мои данные игрушки.

    df <- tibble::tribble(
    ~date1,      ~A Equity,  ~date2,          ~B Equity, ~date3,     ~C Equity,
    "1/29/2016",        35,  "10/31/2017",     67,       NA_character_,  NA_real_,
    "2/29/2016",        40,  "11/30/2017",     31,       NA_character_,  NA_real_,
    NA_character_,NA_real_,  "12/29/2017",     56,       NA_character_,  NA_real_)

В реальном есть более 1000 столбцов и много других дат.

Я хочу увеличить данные так, чтобы желаемый вывод имел только столбцы даты, переменной и значения, как показано ниже :

desired_df <- tibble::tribble(
         ~date,   ~var,  ~value,
   "1/29/2016",  "A",      35,
   "2/29/2016",  "A",      40,
  "10/31/2017",  "B",      67,
  "11/30/2017",  "B",      31,
  "12/29/2017",  "B",      56)

Я пробовал это, но не получил желаемого результата:

df2 <- df %>% 
  pivot_longer(cols = contains("date"), names_to = "dates", values_to = "date") %>% 
  pivot_longer (cols = contains("Equity"), names_to = "var", values_to = "value") %>% 
  select(-dates) %>% 
  distinct() %>% 
  filter(!is.na(date))

Ответы [ 2 ]

5 голосов
/ 09 марта 2020

Если names_to является символом, содержащим специальное .value, значение values_to будет игнорироваться, а имя столбца значения будет получено из части имен существующих столбцов.

library(tidyverse)

## extract stock names
stock <- sub("_Equity", "", grep("Equity$", names(df), value = T))

df %>%
  rename_at(vars(starts_with("date")), ~ str_c(stock, "_date")) %>%
  rename_at(vars(ends_with("Equity")), ~ str_c(stock, "_value")) %>%
  pivot_longer(everything(),
               names_to = c("var", ".value"),
               names_sep = "_",
               values_drop_na = TRUE)

# # A tibble: 5 x 3
#   var   date       value
#   <chr> <chr>      <dbl>
# 1 A     1/29/2016     35
# 2 B     10/31/2017    67
# 3 A     2/29/2016     40
# 4 B     11/30/2017    31
# 5 B     12/29/2017    56

Данные

df <- structure(list(date1 = c("1/29/2016", "2/29/2016", NA), A_Equity = c(35, 
40, NA), date2 = c("10/31/2017", "11/30/2017", "12/29/2017"), 
    B_Equity = c(67, 31, 56), date3 = c(NA_character_, NA_character_, 
    NA_character_), C_Equity = c(NA_real_, NA_real_, NA_real_
    )), row.names = c(NA, -3L), class = c("tbl_df", "tbl", "data.frame"))
2 голосов
/ 09 марта 2020

Базовое решение R с использованием reshape (да, оно все еще там).

setNames(
  na.omit(
    reshape(
      as.data.frame(df), direction="long", varying=1:6, sep="")), 
  c("var","date","value","id"))

    var       date value id
1.1   1  1/29/2016    35  1
2.1   1  2/29/2016    40  2
1.2   2 10/31/2017    67  1
2.2   2 11/30/2017    31  2
3.2   2 12/29/2017    56  3

А если в ваших "игрушечных" данных есть больше столбцов, просто измените значение на :

grep("^[var|date]", names(df))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...