跨行排序以获得三个最大值

时间:2019-02-04 23:54:18

标签: r

有一个名为ISS score的伤害得分

我有一个根据pt ID成行的伤害数据表。

我想获取6个伤害列的前三个值。

列值的范围是0-5。

pt_id head face abdo pelvis Extremity External
1    4    0    0    1    0    3
2    3    3    5    0    3    2
3    0    0    2    1    1    1
4    2    0    0    0    0    1
5    5    0    0    2    0    1

我在上面示例中的输出为

pt-id n1 n2 n3
1    4    3    1
2    5    3    3
3    2    1    1
4    2    1    0
5    5    2    1

值可以在列表中或在新列中,因为从那时起,计算分数很简单。

我曾经以为我可以为6个伤害列创建一个列表,然后对每个列表进行排序,并采用前三个值。我的代码是:

ais$ais_list <- setNames(split(ais[,2:7], seq(nrow(ais))), rownames(ais))

但是我很难将排序应用于数据框内的列表,因为不幸的是,我的数据集中的某些数据包含NA值

1 个答案:

答案 0 :(得分:1)

我们可以按行使用apply和数据框sort,并且每行仅获取前三个值。

cbind(df[1], t(apply(df[-1], 1, sort, decreasing = TRUE)[1:3, ]))

#  pt_id 1 2 3
#1     1 4 3 1
#2     2 5 3 3
#3     3 2 1 1
#4     4 2 1 0
#5     5 5 2 1

由于某些值可能包含NA,因此我们最好apply sort使用匿名函数,然后使用head取前3个值。

cbind(df[1], t(apply(df[-1], 1, function(x) head(sort(x, decreasing = TRUE), 3))))

tidyverse选项的作用是首先gather数据,以降序arrange数据,对于每一行,仅选择前三个值。然后,将injury列替换为所需的列名,最后spread将数据恢复为宽格式。

library(tidyverse)

df %>%
  gather(injury, value, -pt_id) %>%
  arrange(desc(value)) %>%
  group_by(pt_id) %>%
  slice(1:3) %>%
  mutate(injury = 1:3) %>%
  spread(injury, value)

#  pt_id   `1`   `2`   `3`
#  <int> <int> <int> <int>
#1     1     4     3     1
#2     2     5     3     3
#3     3     2     1     1
#4     4     2     1     0
#5     5     5     2     1