【问题标题】:Nested pipe chain in dplyr / left_joindplyr / left_join 中的嵌套管道链
【发布时间】:2018-06-12 23:08:47
【问题描述】:

在尝试获取分组滞后变量的过程中(仅使用 lag 是不可能的),建议的解决方案是提取数据,滞后不同的行,然后重新加入它。

我更喜欢在不创建中间对象的情况下执行此操作,并且希望在链中执行此操作。但是它似乎没有像我预期的那样工作,问题似乎是使用. 和left_join 内的嵌套链之间的一些交互。

require(tidyverse)
#> Loading required package: tidyverse
df <- data.frame(Team = c("A", "A", "A", "A", "B", "B", "B", "C", "C", "D", "D"),
                 Date = c("2016-05-10","2016-05-10", "2016-05-10", "2016-05-10",
                          "2016-05-12", "2016-05-12", "2016-05-12",
                          "2016-05-15","2016-05-15",
                          "2016-05-30", "2016-05-30"), 
                 Points = c(1,4,3,2,1,5,6,1,2,3,9)
)


#This works:
df %>% left_join(x = ., y = df %>% 
                   distinct(Team, Date) %>% 
                   mutate(Date_Lagged = lag(Date)))
#> Joining, by = c("Team", "Date")
#>    Team       Date Points Date_Lagged
#> 1     A 2016-05-10      1        <NA>
#> 2     A 2016-05-10      4        <NA>
#> 3     A 2016-05-10      3        <NA>
#> 4     A 2016-05-10      2        <NA>
#> 5     B 2016-05-12      1  2016-05-10
#> 6     B 2016-05-12      5  2016-05-10
#> 7     B 2016-05-12      6  2016-05-10
#> 8     C 2016-05-15      1  2016-05-12
#> 9     C 2016-05-15      2  2016-05-12
#> 10    D 2016-05-30      3  2016-05-15
#> 11    D 2016-05-30      9  2016-05-15

#And this works:
df %>% left_join(x = ., y = .)
#> Joining, by = c("Team", "Date", "Points")
#>    Team       Date Points
#> 1     A 2016-05-10      1
#> 2     A 2016-05-10      4
#> 3     A 2016-05-10      3
#> 4     A 2016-05-10      2
#> 5     B 2016-05-12      1
#> 6     B 2016-05-12      5
#> 7     B 2016-05-12      6
#> 8     C 2016-05-15      1
#> 9     C 2016-05-15      2
#> 10    D 2016-05-30      3
#> 11    D 2016-05-30      9

#This doesn't work despite the fact that `.` is df.  
df %>% left_join(x = ., y = . %>% 
                   distinct(Team, Date) %>% 
                   mutate(Date_Lagged = lag(Date)))
#> Error in UseMethod("tbl_vars"): no applicable method for 'tbl_vars' applied to an object of class "c('fseq', 'function')"



#Desired output
distinct(df, Team, Date) %>%
  mutate(Date_Lagged = lag(Date)) %>%
  right_join(., df) %>%
  select(Team, Date, Points, Date_Lagged)
#> Joining, by = c("Team", "Date")
#>    Team       Date Points Date_Lagged
#> 1     A 2016-05-10      1        <NA>
#> 2     A 2016-05-10      4        <NA>
#> 3     A 2016-05-10      3        <NA>
#> 4     A 2016-05-10      2        <NA>
#> 5     B 2016-05-12      1  2016-05-10
#> 6     B 2016-05-12      5  2016-05-10
#> 7     B 2016-05-12      6  2016-05-10
#> 8     C 2016-05-15      1  2016-05-12
#> 9     C 2016-05-15      2  2016-05-12
#> 10    D 2016-05-30      3  2016-05-15
#> 11    D 2016-05-30      9  2016-05-15

reprex package (v0.2.0) 于 2018 年 6 月 12 日创建。

【问题讨论】:

标签: r dplyr


【解决方案1】:

为了使您的代码正常工作,您需要在y 参数周围加上一个花括号,如下所示

  df %>% left_join(x = ., y = {.} %>% 
                   distinct(Team, Date) %>% 
                   mutate(Date_Lagged = lag(Date)))

Joining, by = c("Team", "Date")
   Team       Date Points Date_Lagged
1     A 2016-05-10      1        <NA>
2     A 2016-05-10      4        <NA>
3     A 2016-05-10      3        <NA>
4     A 2016-05-10      2        <NA>
5     B 2016-05-12      1  2016-05-10
6     B 2016-05-12      5  2016-05-10
7     B 2016-05-12      6  2016-05-10
8     C 2016-05-15      1  2016-05-12
9     C 2016-05-15      2  2016-05-12
10    D 2016-05-30      3  2016-05-15
11    D 2016-05-30      9  2016-05-15

你可以这样做

df %>% left_join(df%>% 
                   distinct(Team, Date) %>% 
                   mutate(Date_Lagged = lag(Date)))

【讨论】:

  • 这也有效:df %&gt;% left_join({.} %&gt;% distinct(Team, Date) %&gt;% mutate(Date_Lagged = lag(Date)))
  • @HAVB 很棒。 +10
  • 嘿只是一个问题 {.} 是什么意思?
  • @Ian.T . 是管道函数带来的参数。 OP 想使用相同的参数两次。因此必须将第二个作为表达式括起来,否则您将再次在其上使用管道运算符
【解决方案2】:

虽然这不是我的问题的答案(Onyambo 提供了这个!),但我想分享一下,我找到了另一种方法来完成同样的事情。基本上你使用group_by()nest() 来挤压tibble 并消除重复的变量,做滞后,然后unnest()

df %>% 
  group_by(Team, Date) %>% 
  nest() %>% 
  mutate(Date_Lagged = lag(Date)) %>% 
  unnest()
#> # A tibble: 11 x 4
#>    Team  Date       Date_Lagged Points
#>    <fct> <fct>      <fct>        <dbl>
#>  1 A     2016-05-10 <NA>             1
#>  2 A     2016-05-10 <NA>             4
#>  3 A     2016-05-10 <NA>             3
#>  4 A     2016-05-10 <NA>             2
#>  5 B     2016-05-12 2016-05-10       1
#>  6 B     2016-05-12 2016-05-10       5
#>  7 B     2016-05-12 2016-05-10       6
#>  8 C     2016-05-15 2016-05-12       1
#>  9 C     2016-05-15 2016-05-12       2
#> 10 D     2016-05-30 2016-05-15       3
#> 11 D     2016-05-30 2016-05-15       9

reprex package (v0.2.0) 于 2018 年 6 月 14 日创建。

【讨论】:

  • 这是一个了不起的答案。我以前从未见过这个
【解决方案3】:

如果您不介意将管道嵌套替换为函数嵌套,这可以实现您的目标:

df %>% left_join(mutate(distinct(., Team, Date), Date_Lagged = lag(Date)))

输出:

Joining, by = c("Team", "Date")
   Team       Date Points Date_Lagged
1     A 2016-05-10      1        <NA>
2     A 2016-05-10      4        <NA>
3     A 2016-05-10      3        <NA>
4     A 2016-05-10      2        <NA>
5     B 2016-05-12      1  2016-05-10
6     B 2016-05-12      5  2016-05-10
7     B 2016-05-12      6  2016-05-10
8     C 2016-05-15      1  2016-05-12
9     C 2016-05-15      2  2016-05-12
10    D 2016-05-30      3  2016-05-15
11    D 2016-05-30      9  2016-05-15

【讨论】:

    猜你喜欢
    • 2016-04-21
    • 1970-01-01
    • 2018-11-05
    • 2015-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-25
    相关资源
    最近更新 更多