使用tidyr :: pivot_longer为列表中的列分配不同的名称,并将其组合

时间:2019-10-31 05:57:44

标签: r list

我正在提取“宽”数据,打算使用tidyr::pivot_longer()进行整理。

library(tidyverse)

df1 <-
  data.frame(
    M = words[1:10],
    N = rnorm(10, 3, 3),
    O = rnorm(10, 3, 3),
    P = rnorm(10, 3, 3)
  )

df2 <-
  data.frame(
    M = words[1:10],
    N = rnorm(10, 3, 3),
    O = rnorm(10, 3, 3),
    P = rnorm(10, 3, 3)
  )

df3 <-
  data.frame(
    M = words[1:10],
    N = rnorm(10, 3, 3),
    O = rnorm(10, 3, 3),
    P = rnorm(10, 3, 3)
  )

df4 <-
  data.frame(
    M = words[1:10],
    N = rnorm(10, 3, 3),
    O = rnorm(10, 3, 3),
    P = rnorm(10, 3, 3)
  )

lst <- list(df1, df2, df3, df4)

colname <-
  c("ticker", "2017", "2018", "2019")
header <- list("Leverage", "Gearing", "Capex.to.sales", "FCFex")

lst <- lst %>% 
  lapply(setNames, colname) %>% 
  lapply(pivot_longer, -ticker, names_to = "Period", values_to = header)

使用values_to = header会给我这个错误:

  

[[<-。data.frame( tmp `,“ .value”,value = list(“ Leverage”,:     替换有4行,数据有3

相反,我必须使用默认的values_to = "value",然后使用此代码重命名我的列:

lst <- lst %>% 
  lapply(setNames, colname) %>% 
  lapply(pivot_longer, -ticker, names_to = "Period", values_to = "value")

lst <- map(seq_along(lst), function(i){
  x <- lst[[i]]
  colnames(x)[3] <- header[[i]]
  x
})

我的输出显示如下(重命名的列),但是我想知道是否有一种方法可以将向量送入values_to而不是使用map(因为这样做可以更好地进行管道传输)?还是有一种更有效的方法来解决这个问题?

> lst
[[1]]
# A tibble: 30 x 3
   ticker   Period Leverage
   <fct>    <chr>     <dbl>
 1 a        2017      6.01 
 2 a        2018      4.82 
 3 a        2019      1.58 
 4 able     2017      8.64 
 5 able     2018      6.70 
 6 able     2019      0.831
 7 about    2017     -0.187
 8 about    2018      0.549
 9 about    2019      0.829
10 absolute 2017      1.26 
# ... with 20 more rows

[[2]]
# A tibble: 30 x 3
   ticker   Period Gearing
   <fct>    <chr>    <dbl>
 1 a        2017    2.37  
 2 a        2018    3.58  
 3 a        2019    5.63  
 4 able     2017    0.311 
 5 able     2018    0.708 
 6 able     2019   -0.0651
 7 about    2017    2.89  
 8 about    2018    6.25  
 9 about    2019   10.1   
10 absolute 2017    6.48  
# ... with 20 more rows

[[3]]
# A tibble: 30 x 3
   ticker   Period Capex.to.sales
   <fct>    <chr>           <dbl>
 1 a        2017            5.22 
 2 a        2018            1.88 
 3 a        2019            0.746
 4 able     2017           -3.90 
 5 able     2018            3.06 
 6 able     2019            1.91 
 7 about    2017            1.35 
 8 about    2018            4.12 
 9 about    2019           11.1  
10 absolute 2017            1.76 
# ... with 20 more rows

[[4]]
# A tibble: 30 x 3
   ticker   Period  FCFex
   <fct>    <chr>   <dbl>
 1 a        2017    1.76 
 2 a        2018    2.85 
 3 a        2019    1.86 
 4 able     2017   -3.38 
 5 able     2018   -3.02 
 6 able     2019   -1.52 
 7 about    2017    6.46 
 8 about    2018    5.39 
 9 about    2019    0.810
10 absolute 2017    8.08 
# ... with 20 more rows

对于我的问题的第二部分,我打算使用bind_col()将所有四个数据帧组合为一个,但是两个公共列正在重复(如下所示)。

如何告诉R仅绑定重命名的最右边的列,即排除最后三个数据帧的前两列?谢谢。

Metrics <- bind_cols(lst)

> Metrics
# A tibble: 30 x 12
   ticker Period Leverage ticker1 Period1 Gearing ticker2 Period2
   <fct>  <chr>     <dbl> <fct>   <chr>     <dbl> <fct>   <chr>  
 1 a      2017      6.01  a       2017     2.37   a       2017   
 2 a      2018      4.82  a       2018     3.58   a       2018   
 3 a      2019      1.58  a       2019     5.63   a       2019   
 4 able   2017      8.64  able    2017     0.311  able    2017   
 5 able   2018      6.70  able    2018     0.708  able    2018   
 6 able   2019      0.831 able    2019    -0.0651 able    2019   
 7 about  2017     -0.187 about   2017     2.89   about   2017   
 8 about  2018      0.549 about   2018     6.25   about   2018   
 9 about  2019      0.829 about   2019    10.1    about   2019   
10 absol~ 2017      1.26  absolu~ 2017     6.48   absolu~ 2017   
# ... with 20 more rows, and 4 more variables: Capex.to.sales <dbl>,
#   ticker3 <fct>, Period3 <chr>, FCFex <dbl>

1 个答案:

答案 0 :(得分:0)

您可以使用public static function boot() { parent::boot(); // create a event to happen on updating static::updating(function ($table) { $table->updated_by = Auth::user()->id; }); // create a event to happen on saving static::saving(function ($table) { $table->created_by = Auth::user()->id; }); } 来做到这一点:

purrr

输出:

library(purrr)

lst <- map(lst, setNames, colname)

map2_dfc(lst, header, ~ pivot_longer(
  .x, -ticker, names_to = "Period", values_to = .y)) %>% 
  select(c(1:3, 6, 9, 12))