如何根据自定义顺序对列进行排序?

时间:2020-07-22 11:32:15

标签: r tidyverse

我有两个数据帧private Sprite[] sprites; void Start() { sprites = Resources.LoadAll<Sprite>("lofiEnvironment2"); print(sprites.Length); // 0 dfdf2df2的派生数据帧。它们都如下图所示:

df

现在,我想加入它们并对列进行排序,以使组中的第一列是df <- structure(list(A = c(100, 0, 0, 0, 0), B = c(10, 10, 10, 10, 10)), class = "data.frame", row.names = c(NA, -5L)) A B 1 100 10 2 0 10 3 0 10 4 0 10 5 0 10 df2 <- structure(list(A_h1 = c(50, 33.3333333333333, 11.1111111111111, 3.7037037037037, 1.23456790123457), A_h2 = c(21.9223593595585, 28.0776406404415, 17.9805898398896, 11.5145576200828, 7.3737868649931 ), A_h3 = c(13.5918399333808, 20.6783494527816, 15.7298106138376, 11.9655073298858, 9.10204001665479), B_h1 = c(5, 8.33333333333333, 9.44444444444444, 9.81481481481481, 9.93827160493827), B_h2 = c(2.19223593595585, 5, 6.79805898398896, 7.94951474599724, 8.68689343249655), B_h3 = c(1.35918399333808, 3.42701893861624, 5, 6.19655073298858, 7.10675473465406)), class = "data.frame", row.names = c(NA, -5L)) A_h1 A_h2 A_h3 B_h1 B_h2 B_h3 1 50.000000 21.922359 13.59184 5.000000 2.192236 1.359184 2 33.333333 28.077641 20.67835 8.333333 5.000000 3.427019 3 11.111111 17.980590 15.72981 9.444444 6.798059 5.000000 4 3.703704 11.514558 11.96551 9.814815 7.949515 6.196551 5 1.234568 7.373787 9.10204 9.938272 8.686893 7.106755 中的原始列。所以输出看起来像这样:

df

但是,我不知道原始列的数量或名称,因此整个订购过程必须考虑到这一点。我该如何实现?

5 个答案:

答案 0 :(得分:2)

这是基本的R单缸纸。

final <- cbind(df, df2)[order(c(names(df), names(df2)))]

final
#    A      A_h1      A_h2     A_h3  B     B_h1     B_h2     B_h3
#1 100 50.000000 21.922359 13.59184 10 5.000000 2.192236 1.359184
#2   0 33.333333 28.077641 20.67835 10 8.333333 5.000000 3.427019
#3   0 11.111111 17.980590 15.72981 10 9.444444 6.798059 5.000000
#4   0  3.703704 11.514558 11.96551 10 9.814815 7.949515 6.196551
#5   0  1.234568  7.373787  9.10204 10 9.938272 8.686893 7.106755

编辑

在OP的comment之后,这是一个解决此问题新版本的功能。

不幸的是,这按字母顺序对结果进行排序。请注意 如果df中的列具有B, A的顺序,则结果应具有B, B_h1, B_h2, B_h3, A, A_h1, A_h2, A_h3的顺序。

fun <- function(X, Y){
  res <- lapply(names(X), function(i){
    j <- grep(i, names(Y))
    cbind(X[i], Y[j])
  })
  do.call(cbind, res)
}

fun(df, df2)
fun(df1, df2)

答案 1 :(得分:1)

dfdf2的名称之间找到可用于match的通用模式。对于共享的示例,您可以删除下划线后的所有内容。

newdf <- cbind(df, df2)
newdf[order(match(sub('_.*', '', names(newdf)), names(df)))]

#   A      A_h1      A_h2     A_h3  B     B_h1     B_h2     B_h3
#1 100 50.000000 21.922359 13.59184 10 5.000000 2.192236 1.359184
#2   0 33.333333 28.077641 20.67835 10 8.333333 5.000000 3.427019
#3   0 11.111111 17.980590 15.72981 10 9.444444 6.798059 5.000000
#4   0  3.703704 11.514558 11.96551 10 9.814815 7.949515 6.196551
#5   0  1.234568  7.373787  9.10204 10 9.938272 8.686893 7.106755

答案 2 :(得分:1)

来自mixedsort的{​​{1}}的选项

gtools

答案 3 :(得分:0)

也许您可以尝试下面的代码

lst <- split.default(df2,gsub("_.*","",names(df2)))
idx <- match(names(df),names(lst))
do.call(cbind,lapply(seq_along(idx), function(k) cbind(df[k],lst[[idx[k]]])))

给出

> do.call(cbind,lapply(seq_along(idx), function(k) cbind(df[k],lst[[idx[k]]])))
    A      A_h1      A_h2     A_h3  B     B_h1     B_h2     B_h3
1 100 50.000000 21.922359 13.59184 10 5.000000 2.192236 1.359184
2   0 33.333333 28.077641 20.67835 10 8.333333 5.000000 3.427019
3   0 11.111111 17.980590 15.72981 10 9.444444 6.798059 5.000000
4   0  3.703704 11.514558 11.96551 10 9.814815 7.949515 6.196551
5   0  1.234568  7.373787  9.10204 10 9.938272 8.686893 7.106755

如果您尝试其他示例

df <- rev(df)
> df
   B   A
1 10 100
2 10   0
3 10   0
4 10   0
5 10   0

您将看到结果

> do.call(cbind,lapply(seq_along(idx), function(k) cbind(df[k],lst[[idx[k]]])))
   B     B_h1     B_h2     B_h3   A      A_h1      A_h2     A_h3
1 10 5.000000 2.192236 1.359184 100 50.000000 21.922359 13.59184
2 10 8.333333 5.000000 3.427019   0 33.333333 28.077641 20.67835
3 10 9.444444 6.798059 5.000000   0 11.111111 17.980590 15.72981
4 10 9.814815 7.949515 6.196551   0  3.703704 11.514558 11.96551
5 10 9.938272 8.686893 7.106755   0  1.234568  7.373787  9.10204

答案 4 :(得分:0)

这里是dplyr软件包的替代方法。根据问题中的dfdf2,代码和输出如下。

library(dplyr)
df3 <- data.frame(df, df2) %>% 
      select(starts_with("A"), everything())
df3 


#    A      A_h1      A_h2     A_h3  B     B_h1     B_h2     B_h3
#1 100 50.000000 21.922359 13.59184 10 5.000000 2.192236 1.359184
#2   0 33.333333 28.077641 20.67835 10 8.333333 5.000000 3.427019
#3   0 11.111111 17.980590 15.72981 10 9.444444 6.798059 5.000000
#4   0  3.703704 11.514558 11.96551 10 9.814815 7.949515 6.196551
#5   0  1.234568  7.373787  9.10204 10 9.938272 8.686893 7.106755