我想根据字符串名称和每列中的第一个非零值对列进行排序。
假设我有以下数据:
col1_A col2_A col1_B col2_B
0 0 0 0
0 2 0 4
3 12 1 1
我需要以这样的方式对它们进行排序:名称包含“_A”的列放在“_B”之前,然后第一个非零值的列排在前面。预期输出将是:
col2_A col1_A col1_B col2_B
0 0 0 0
2 0 4 0
12 3 1 1
这是用于复制的示例数据。
df = data.frame('col1_A'=c(0,0,3),'col2_A'=c(0,2,12),'col1_B'=c(0,0,1),'col2_B'=c(0,4,1))
更新:
Colnames 只是示例,只有最后一个字符很重要!因此我现在将它们更改为这样以避免混淆。
最佳答案
这是使用 split.default
的另一种方法 -
purrr::map_dfc(split.default(df, sub('.*_', '', names(df))), function(x) {
x[order(sapply(x, function(x) match(TRUE, x !=0)))]
})
# col2_A col1_A col2_B col1_B
#1 0 0 0 0
#2 2 0 4 0
#3 12 3 1 1
sub
仅保留输出中重要的最后一个字符。我们相应地分割数据。
sub('.*_', '', names(df))
#[1] "A" "A" "B" "B"
对于每个组(A
和 B
),我们提取第一个非零值的位置 (match(TRUE, x!= 0)
) 并使用 order
重新排列数据框。 map_dfc
用于将数据帧列表合并到一个组合数据帧中。
关于使用 dplyr 根据第一个非零值重新定位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69072058/