根据R中不同列中的值对列中的值进行排序

时间:2019-07-20 09:34:44

标签: r sorting panel

我具有以下面板数据集:

group  i  f  r  d
1      4  8  3  3
1      9  4  5  1
1      2  2  2  2
2      5  5  3  2
2      3  9  3  3
2      9  1  3  1

我想根据每个组的d列中的值对该数据帧中的i列重新排序。因此,第i列中第1组的最大值应对应于d列中的最大值。最后,我的data.frame应该看起来像这样:

group  i  f  r  d
1      9  8  3  3
1      2  4  5  1
1      4  2  2  2
2      5  5  3  2
2      9  9  3  3
2      3  1  3  1

4 个答案:

答案 0 :(得分:4)

这是一个dplyr解决方案。

首先,按group分组。然后在临时的新列d中获得列ord的排列重排,并使用它来重新排序i

library(dplyr)

df1 %>%
  group_by(group) %>%
  mutate(ord = order(d),
         i = i[ord]) %>%
  ungroup() %>%
  select(-ord)
## A tibble: 6 x 5
#  group     i     f     r     d
#  <int> <int> <int> <int> <int>
#1     1     9     8     3     3
#2     1     2     4     5     1
#3     1     4     2     2     2
#4     2     9     5     3     2
#5     2     5     9     3     3
#6     2     3     1     3     1

答案 1 :(得分:3)

原始(错误)

您可以使用dplyrrank来实现:

library(dplyr)

df1 %>% group_by(group) %>%
  mutate(i = i[rev(rank(d))])

编辑

这个问题实际上比最初看起来要棘手,我发布的原始答案不正确。正确的解决方案按i排序,然后再按d的等级进行排序。这给出了OP所需的输出,而我以前的答案没有(不引起注意!)

df1 %>% group_by(group) %>%
  mutate(i = i[order(i)][rank(d)])
# A tibble: 6 x 5
# Groups:   group [2]
#  group     i     f     r     d
#  <int> <int> <int> <int> <int>
#1     1     9     8     3     3
#2     1     2     4     5     1
#3     1     4     2     2     2
#4     2     5     5     3     2
#5     2     9     9     3     3
#6     2     3     1     3     1

答案 2 :(得分:2)

带有data.table

的选项
library(data.table)
setDT(df1)[, i := i[order(d)], group]
df1
#   group i f r d
#1:     1 9 8 3 3
#2:     1 2 4 5 1
#3:     1 4 2 2 2
#4:     2 9 5 3 2
#5:     2 5 9 3 3
#6:     2 3 1 3 1

如果需要第二版

setDT(df1)[, i := sort(i)[d], group]

数据

df1 <- structure(list(group = c(1L, 1L, 1L, 2L, 2L, 2L), i = c(4L, 9L, 
2L, 5L, 3L, 9L), f = c(8L, 4L, 2L, 5L, 9L, 1L), r = c(3L, 5L, 
2L, 3L, 3L, 3L), d = c(3L, 1L, 2L, 2L, 3L, 1L)), class = "data.frame",
row.names = c(NA, 
-6L))

答案 3 :(得分:1)

关于预期输出有些困惑。在这里,我展示了一种获取两个输出版本的方法。

使用splitmapply的基本R

df$i <- c(mapply(function(x, y) sort(y)[x], 
                  split(df$d, df$group), split(df$i, df$group)))

df
#  group i f r d
#1     1 9 8 3 3
#2     1 2 4 5 1
#3     1 4 2 2 2
#4     2 5 5 3 2
#5     2 9 9 3 3
#6     2 3 1 3 1

或其他版本

df$i <- c(mapply(function(x, y) y[order(x)], 
                 split(df$d, df$group), split(df$i, df$group)))

df
#  group i f r d
#1     1 9 8 3 3
#2     1 2 4 5 1
#3     1 4 2 2 2
#4     2 9 5 3 2
#5     2 5 9 3 3
#6     2 3 1 3 1

我们也可以使用dplyr

对于第一个版本

library(dplyr)
df %>%
  group_by(group) %>%
  mutate(i = sort(i)[d])

@Rui已使用order显示第二个版本

df %>%
  group_by(group) %>%
  mutate(i = i[order(d)])