【问题标题】:r - arrange values in column based on unique values in another column within a groupr - 根据组内另一列中的唯一值排列列中的值
【发布时间】:2020-02-08 06:21:34
【问题描述】:

我正在尝试根据组内同一数据框中另一列的唯一值,以降序或升序对数据框中的列进行重新排序。

为了证明这一点,下面给出了一个数据框具有三列的示例。目标是按gr 列分组,并根据b 列的唯一值对a 列进行排序。因此,例如,如果在gr=1 中,b 列的唯一值是 T,那么我希望列 a 按升序排列,如果不是按降序排列。示例如下

# sample dataset
df <-  data.frame(
    a = c(1,3,2,4),
    b = c(T,T,F,F),
    gr = c(1,1,2,2)
  )

# split dataset according to a grouping column
df <- df %>% split(df$gr)

# ordering function
f1 <- function(dt) {
  if (unique(dt$b) == T) {
    arrange(dt, a)
  } else {
    arrange(dt, -a)
  }
}

所需的数据集应如下所示:

# order within groups based on variable b
df %>% purrr::map_df(f1) 

不使用列表或tidyr::nest 可以做到这一点吗?使用简单的dplyr::group_bydplyr::arrange 应该是可能的,并且是最理想的答案。

【问题讨论】:

  • 如果您仔细查看 var a,您会发现它已被重新排序。原来是c(1,3,2,4),最后是c(1,3,4,2)
  • 重新排序已完成。而不是 2,4;需要 4,2
  • 假设如果您有更多行并且特定组有 TRUE/FALSE,顺序将如何变化
  • df %&gt;% arrange(gr, a * if_else(b, 1, -1))
  • d.b 这是最简单的解决方案。但我会接受 Akruns,因为这是最快的回复

标签: r dataframe dplyr


【解决方案1】:

这是一个单独使用arrange 而不做任何split 的选项

library(dplyr)
df %>%
   arrange(gr, c(1, -1)[gr] * a)
#  a     b gr
#1 1  TRUE  1
#2 3  TRUE  1
#3 4 FALSE  2
#4 2 FALSE  2

或者如果它需要与'b'一起使用

df %>% 
   arrange(gr, c(-1, 1)[(b + 1)] * a)
#  a     b gr
#1 1  TRUE  1
#2 3  TRUE  1
#3 4 FALSE  2
#4 2 FALSE  2

在这里,我们使用numeric 'gr'。如果不是numeric,则使用match创建分组索引并使用它来更改'a'的值

df %>%
   arrange(gr, c(1, -1)[match(gr, unique(gr))] * a)

【讨论】:

    【解决方案2】:

    这是一种方法。

    library(dplyr)
    
    f2 <- function(dt) {
      2*as.integer(df$b) - 1
    }
    
    df %>% arrange(gr, a*f2())
    

    如果您接受gr 列的重新排列,请将其从arrange 中删除。

    df %>% arrange(a*f2())
    

    编辑。

    更简单?

    f2 <- function(x) 2*x - 1
    
    df %>% arrange(gr, a*f2(b))
    

    【讨论】:

    • @FaustoCarvalhoMarquesSilva 请注意,根本不需要调用as.integer,R 会将逻辑强制转换为整数,我这样写是为了更清楚。在真实代码中,删除它。
    • @FaustoCarvalhoMarquesSilva 如果您喜欢它,请查看编辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-03
    • 2022-01-23
    • 2017-12-08
    • 2021-03-16
    • 2023-02-23
    • 1970-01-01
    • 2022-11-23
    相关资源
    最近更新 更多