如何重新排序由“,”分隔的列值的升序,并且只保留 R 中的第一个值

How to reorder column values ascending order that are seperated by "," and only keep first value in R

我在 df 中有一列包含如下值:

ID
2
NA
1
3
4
5,7
9,6,10
12
15
16
17
NA
19
22,23

我想根据升序对每一行重新排序。注意 - 此列是基于“字符”的字段,一些行的顺序已经正确。

从那里开始,我只想保留第一个值并删除其他值。

期望的输出:

ID
2
NA
1
3
4
5
6
12
15
16
17
NA
19
22

您可以用逗号拆分数据,sort 它们并提取第一个值。

df$ID <- sapply(strsplit(df$ID, ','), function(x) sort(as.numeric(x))[1])

#   ID
#1   2
#2  NA
#3   1
#4   3
#5   4
#6   5
#7   6
#8  12
#9  15
#10 16
#11 17
#12 NA
#13 19
#14 22

几个 tidyverse 备选方案。

library(tidyverse)

#1.
#Same as base R but in tidyverse
df %>% mutate(ID = map_dbl(str_split(ID, ','), ~sort(as.numeric(.x))[1]))

#2.
df %>%
  mutate(row = row_number()) %>%
  separate_rows(ID, sep = ',', convert = TRUE) %>%
  group_by(row) %>%
  summarise(ID = min(ID)) %>%
  select(-row)

我们可以使用 minimum 而不是排序/提取:

DF <- transform(DF, ID=sapply(strsplit(ID, ','), \(x) min(as.double(x))))
DF
#    ID
# 1   2
# 2  NA
# 3   1
# 4   3
# 5   4
# 6   5
# 7   6
# 8  12
# 9  15
# 10 16
# 11 17
# 12 NA
# 13 19
# 14 22

这是另一个 tidyverse 解决方案:利用 (dyplrpurrrstringrreadr

library(tidyverse)
df %>% 
    mutate(ID = map_chr(str_split(ID, ","), ~ 
                           toString(sort(as.numeric(.x)))),
           ID = parse_number(ID))
)

输出:

   ID
1   2
2  NA
3   1
4   3
5   4
6   5
7   6
8  12
9  15
10 16
11 17
12 NA
13 19
14 22

我们可以使用str_extract

library(stringr)
library(dplyr)
df1 %>%
    mutate(ID = as.numeric(str_extract(ID, '\d+')))

-输出

   ID
1   2
2  NA
3   1
4   3
5   4
6   5
7   9
8  12
9  15
10 16
11 17
12 NA
13 19
14 22

数据

df1 <- structure(list(ID = c("2", NA, "1", "3", "4", "5,7", "9,6,10", 
"12", "15", "16", "17", NA, "19", "22,23")), class = "data.frame", row.names = c(NA, 
-14L))