R 对特定列按行排序
R row-wise sort on specific columns
我想使用特定列进行按行排序,但同时保留原始 df 中的所有列。
数据:
df <- structure(list(C1 = c("ABC", "XYZ", "DEF"),
C2 = c("ZLO", "BCD", "PQR"),
C3 = c("E1", "E2", "E3")),
class = "data.frame", row.names = c(NA, -3L))
Desired output:
C1 C2 C3
ABC ZLO E1
BCD XYZ E2
DEF PQR E3
我尝试使用:
df <- t(apply(df[1:2], 1,
FUN=function(x) sort(x, decreasing=FALSE)))
但它只 returns 前两列,我需要帮助来:
a) 对其进行矢量化
b) 保留所有列
而不是分配给 df
,只分配给您要排序的列。
df[1:2] <- t(apply(df[1:2], 1,
FUN=function(x) sort(x, decreasing=FALSE)))
或者更简单的写法:
to_sort <- 1:2
df[to_sort] <- t(apply(df[to_sort], 1, sort, decreasing = FALSE))
df <- structure(list(C1 = c("ABC", "XYZ", "DEF"),
C2 = c("ZLO", "BCD", "PQR"),
C3 = c("E1", "E2", "E3")),
class = "data.frame", row.names = c(NA, -3L))
解决方案使用 dplyr
和 tidyr
将数据转换为长格式,按行分组并按字符串排序,然后将其恢复为宽格式:
library(dplyr)
library(tidyr)
编辑:
已编辑代码,因此 C3
保持原样
df %>%
mutate(ID = row_number()) %>%
pivot_longer(cols=-c(ID, C3)) %>%
group_by(ID) %>%
arrange(value) %>%
mutate(name = paste0("C", row_number())) %>%
pivot_wider(names_from = name,
values_from = value) %>%
select(C1, C2, C3)
# Groups: ID [3]
ID C1 C2 C3
<int> <chr> <chr> <chr>
1 1 ABC ZLO E1
2 2 BCD XYZ E2
3 3 DEF PQR E3
这是另一个解决方案:
librar(dplyr)
df <- apply(df[1:2], 1, sort) %>%
t() %>%
cbind(df[3]) %>%
as.data.frame() %>%
setNames(paste0("C", 1:length(.)))
# output
C1 C2 C3
1 ABC ZLO E1
2 BCD XYZ E2
3 DEF PQR E3
我想使用特定列进行按行排序,但同时保留原始 df 中的所有列。
数据:
df <- structure(list(C1 = c("ABC", "XYZ", "DEF"),
C2 = c("ZLO", "BCD", "PQR"),
C3 = c("E1", "E2", "E3")),
class = "data.frame", row.names = c(NA, -3L))
Desired output:
C1 C2 C3
ABC ZLO E1
BCD XYZ E2
DEF PQR E3
我尝试使用:
df <- t(apply(df[1:2], 1,
FUN=function(x) sort(x, decreasing=FALSE)))
但它只 returns 前两列,我需要帮助来: a) 对其进行矢量化 b) 保留所有列
而不是分配给 df
,只分配给您要排序的列。
df[1:2] <- t(apply(df[1:2], 1,
FUN=function(x) sort(x, decreasing=FALSE)))
或者更简单的写法:
to_sort <- 1:2
df[to_sort] <- t(apply(df[to_sort], 1, sort, decreasing = FALSE))
df <- structure(list(C1 = c("ABC", "XYZ", "DEF"),
C2 = c("ZLO", "BCD", "PQR"),
C3 = c("E1", "E2", "E3")),
class = "data.frame", row.names = c(NA, -3L))
解决方案使用 dplyr
和 tidyr
将数据转换为长格式,按行分组并按字符串排序,然后将其恢复为宽格式:
library(dplyr)
library(tidyr)
编辑:
已编辑代码,因此 C3
保持原样
df %>%
mutate(ID = row_number()) %>%
pivot_longer(cols=-c(ID, C3)) %>%
group_by(ID) %>%
arrange(value) %>%
mutate(name = paste0("C", row_number())) %>%
pivot_wider(names_from = name,
values_from = value) %>%
select(C1, C2, C3)
# Groups: ID [3]
ID C1 C2 C3
<int> <chr> <chr> <chr>
1 1 ABC ZLO E1
2 2 BCD XYZ E2
3 3 DEF PQR E3
这是另一个解决方案:
librar(dplyr)
df <- apply(df[1:2], 1, sort) %>%
t() %>%
cbind(df[3]) %>%
as.data.frame() %>%
setNames(paste0("C", 1:length(.)))
# output
C1 C2 C3
1 ABC ZLO E1
2 BCD XYZ E2
3 DEF PQR E3