对长数据帧进行排序,好像它很宽

时间:2018-11-24 20:34:03

标签: r dplyr

我希望对长格式的数据框进行排序,就好像它是宽格式一样,但是我不希望更改数据框的结构以使其变宽。如何使用tidyverse / dplyr工具来实现此目的,例如ranging,group,forcats :: fct_reorder等?

一个例子: 如果数据采用的是宽格式,则它将看起来像这样:

df1 <- data.frame(id = c("A", "B", "C"),
              col1 = c(8, 8, 7),
              col2 = c(7, 9, 3))

  id col1 col2
1  A    8    7
2  B    8    9
3  C    7    3

然后我将按照col1然后col2的顺序对两列进行降序排序,因此它将只交换前两行。

实际上,我的格式很长,就像这样:

df2 <- data.frame(id = c("A", "A", "B", "B", "C", "C"),
             type = c(1, 2, 1, 2, 1, 2),
             value = c(8, 7, 8, 9, 7, 3))

  id type value
1  A    1     8
2  A    2     7
3  B    1     8
4  B    2     9
5  C    1     7
6  C    2     3

排序之后,我希望它看起来像这样:

      id type value
1  B    1     8
2  B    2     9
3  A    1     8
4  A    2     7
5  C    1     7
6  C    2     3

为了让我先对类型1的值排序,如果有联系,请查看类型2的值对这些联系进行排序。

2 个答案:

答案 0 :(得分:0)

以下是执行此操作的一种可能方法。它不是很简洁,但是可以完成工作。

library(dplyr)

df2 %>%
  group_by(type) %>%
  arrange(id) %>%
  group_by(id) %>%
  mutate(
    col1 = ifelse(type == 1, value, NA),
    col1 = max(col1, na.rm = T),
    total = sum(value)
  ) %>%
  arrange(desc(col1), desc(total)) %>%
  select(id:value)

# # A tibble: 6 x 3
# # Groups:   id [3]
#   id     type value
#   <fct> <dbl> <dbl>
# 1 B         1     8
# 2 B         2     9
# 3 A         1     8
# 4 A         2     7
# 5 C         1     7
# 6 C         2     3

答案 1 :(得分:0)

使用dcast()-order()-melt()方法。

library(reshape2)
m1 <- dcast(df2, ... ~ id)
m2 <- m1[, order(-m1[2, ])]
m3 <- melt(m2, id=c("type"))
rm(m1, m2)

> m3[, c(2, 1, 3)]
  variable type value
1        B    1     8
2        B    2     9
3        A    1     8
4        A    2     7
5        C    1     7
6        C    2     3

数据

> dput(df2)
structure(list(id = structure(c(1L, 1L, 2L, 2L, 3L, 3L), .Label = c("A", 
"B", "C"), class = "factor"), type = c(1, 2, 1, 2, 1, 2), value = c(8, 
7, 8, 9, 7, 3)), class = "data.frame", row.names = c(NA, -6L))