【问题标题】:How to pivot_long pairs of date-var combinations with non-matching dates?如何pivot_long 对具有不匹配日期的日期变量组合?
【发布时间】:2020-03-09 11:55:22
【问题描述】:

这是我的玩具数据。

    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 多列和更多的日期。

我想将数据加长,以便所需的输出只有 date、var 和 value 列,如下所示:

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))

【问题讨论】:

    标签: r dplyr tidyr purrr


    【解决方案1】:

    如果names_to 是包含特殊.value 的字符,则values_to 值将被忽略,值列的名称将派生自现有列名的一部分。

    library(tidyverse)
    
    ## extract stock names
    stock <- sub("_Equity", "", grep("Equity$", names(df), value = TRUE))
    
    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"))
    

    【讨论】:

    • 我很惊讶pivot_longer 中没有处理名称的参数
    • 而不是 var1, var2,... 我的股票代码名称都以单词“Equity”结尾。您现在可以提出更改建议吗?
    • @Geet 你能提供示例列名吗?我需要知道列名的实际模式。
    • 好的。我更新了数据框df。只是所有 var* 变量都是股票代码名称,都以单词“Equity”结尾。
    • @Geet 带有空格的列名无效。请将A Equity 替换为A_Equity 并运行我的代码。
    【解决方案2】:

    Base 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))
    

    【讨论】:

      猜你喜欢
      • 2019-02-18
      • 1970-01-01
      • 1970-01-01
      • 2019-01-24
      • 2021-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多