我正在寻找一个简单的 dplyr 或 data.table 解决方案。我需要对大型数据框的行进行排序,但只有 for 循环的解决方案。
这是一个最小的示例:
A = c('A1', 'A2', 'A3', 'A4', 'A5')
B = c('B1', 'B2', 'B3')
set.seed(20)
df = data.frame(col1 = sample(c(A,B),8,1), col2 = sample(c(A,B),8,1), col3 = sample(c(A,B),8,1))
col1 col2 col3
1 B1 B1 A1
2 B2 B1 A5
3 A3 A5 B1
4 B3 B2 B3
5 A2 B2 A2
6 A1 A1 B2
7 A2 A3 A4
8 A5 A5 A1
预期输出应该是:
col1 col2 col3
1 B1 A1 B1
2 B1 A5 B2
3 B1 A3 A5
4 B2 B3 B3
5 B2 A2 A2
6 B2 A1 A1
7 A2 A3 A4
8 A1 A5 A5
因此,排序算法的行顺序为 c('B1', 'B2', 'B3', 'A1', 'A2', 'A3', 'A4', 'A5 ')
但有一个异常(exception)。如果第一列中已经有一个 B,我们将继续使用 A。
下一个问题是,我在数据框中还有另外三列,它们的编号不同,应该按照与这三列相同的顺序重新排列。
最佳答案
您可以以不同的顺序使用apply
、factor
和sort
两次。
order1 = c('B1', 'B2', 'B3', 'A1', 'A2', 'A3', 'A4', 'A5') #Main order
order2 = c('A1', 'A2', 'A3', 'A4', 'A5', 'B1', 'B2', 'B3') #Secondary order for rows with 1st column as "B"
startB <- grepl("B", df[, 1]) #Rows with 1st column being "B"
df <- data.frame(t(apply(df, 1, \(x) sort(factor(x, levels = order1)))))
df[startB, -1] <- t(apply(df[startB, ], 1, \(x) sort(factor(x[-1], levels = order2))))
输出
X1 X2 X3
1 B1 A1 B1
2 B1 A5 B2
3 B1 A3 A5
4 B2 B3 B3
5 B2 A2 A2
6 B2 A1 A1
7 A2 A3 A4
8 A1 A5 A5
关于r - 对数据框的行进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72098832/