代码之家  ›  专栏  ›  技术社区  ›  Shawn Janzen

为什么R dplyr不能使用for循环中的向量元素正确地排列排序

  •  0
  • Shawn Janzen  · 技术社区  · 4 年前

    在for循环中使用r的dplyr::arrange()时,我很难使其正确排序。我发现很多帖子都在讨论这个问题(比如 ex.1 在.by_group=TRUE并且使用desc()better的情况下, ex.2 带有列表,以及 ex.3 使用filter_all()和%in%)。然而,我仍然有点难以理解为什么当我直接使用列名时,我可以让arrange()工作,而当我引用它在向量中的索引位置时,却不能工作,这将在稍后的循环中用于帮助从更大的数据帧中提取数据。

    以下是一个可复制的玩具数据,用于演示:

    set.seed(1) 
    toy <- data.frame(a=rep(sample(letters[1:5], 4, TRUE)), tf=sample(c("T","F"), 100, TRUE), n1=sample(1:100, 100, TRUE), n2=1:100)
    get_it <- colnames(toy)[3:4]
    

    到目前为止,我的初始方法适用于select()部分的索引向量,但即使使用.by_group选项,也无法对arrange()进行排序。我还尝试添加dplyr::arrange(),但没有更改。

    j=1  # pretending this is the 1st pass in the loop
    toy %>% 
      select(a, tf, get_it[j]) %>% 
      group_by(a) %>% 
      arrange(desc(get_it[j]), .by_group=TRUE)
    
       a     tf     n1
    <chr>  <chr>  <int>
       a      T     21
       a      T     17
       a      F     87
       a      T     90
       a      T     64  
    

    示例输出被截断

    然而,当我在arrange()中为列的相同名称切换索引向量时,我会得到预期的排序结果(select仍然很好):

    j=1  # pretending this is the 1st pass through the loop
    toy %>% 
      select(a, tf, get_it[j]) %>% 
      group_by(a) %>% 
      arrange(desc(n1), .by_group=TRUE)
    
       a     tf     n1
    <chr>  <chr>  <int>
       a      F     99
       a      F     98
       a      F     96
       a      F     95
       a      T     93  
    

    示例输出被截断

    为什么第二个版本有效,而第一个版本无效?我应该更改什么,以便可以在多个列中循环使用它?
    提前感谢!感谢您抽出时间!

    (小编辑以更正拼写错误。)

    0 回复  |  直到 4 年前
        1
  •  1
  •   r2evans    4 年前

    这是“ programming with dplyr “,使用 .data 用于通过字符串引用列:

    toy %>% 
      select(a, tf, get_it[j]) %>% 
      group_by(a) %>% 
      arrange(desc(.data[[ get_it[j] ]]), .by_group=TRUE)
    # # A tibble: 100 x 3
    # # Groups:   a [3]
    #    a     tf       n1
    #    <chr> <chr> <int>
    #  1 a     F        99
    #  2 a     F        98
    #  3 a     F        96
    #  4 a     F        95
    #  5 a     T        93
    #  6 a     T        92
    #  7 a     T        92
    #  8 a     T        90
    #  9 a     F        87
    # 10 a     F        86
    # # ... with 90 more rows