使用R中的截止值对多个列进行排序

时间:2015-12-08 16:15:40

标签: r sorting dataframe

给定n列,我希望第一列按降序排列,直到达到截止值,然后排序第二列,依此类推。解释起来有点棘手,所以这里有一个最简单案例的例子,有两列:

df <- structure(list(x = c(0.92, 0.9, 0.9, 0.88, 0.86, 0.52, 0.35, 0.28, 0.02, -0.03, 
-0.02, -0.06, -0.06, -0.01, -0.01, 0.01, -0.03, -0.03, 0.01, 0.05, -0.01), 
y = c(0.03, -0.01, -0.03, 0, 0.02, 0.01, -0.08, 0.04, 0.71, 0.71, 0.69, 0.57,
 0.55, 0.52, 0.4, -0.37, 0.37, 0.36, -0.34, -0.33, -0.32)), 
.Names = c("x", "y"), row.names = c(NA, 21L), class = "data.frame")

订购后,df看起来像这样:

df[with(df, order (-abs(df$x), -abs(df$y))),]
       x     y
1   0.92  0.03
3   0.90 -0.03
2   0.90 -0.01
4   0.88  0.00
5   0.86  0.02
6   0.52  0.01
7   0.35 -0.08
8   0.28  0.04
12 -0.06  0.57
13 -0.06  0.55
20  0.05 -0.33
10 -0.03  0.71
17 -0.03  0.37
18 -0.03  0.36
9   0.02  0.71
11 -0.02  0.69
14 -0.01  0.52
15 -0.01  0.40
16  0.01 -0.37
19  0.01 -0.34
21 -0.01 -0.32

仅按预期排序列x。但是,如果我想建立.32的截止值,那么第一列中的变量按降序排列,直到值<1。 .32,然后它切换到订购第二列,我该怎么做?

我可以通过将NA分配给值&lt; .32,但我需要保留所有值,只需以类似的方式对它们进行排序!

df.na<-df
df.na[abs(df.na)<.32]<-NA
df.na[with(df.na, order (-abs(df.na$x), -abs(df.na$y))),]
      x     y
1  0.92    NA
2  0.90    NA
3  0.90    NA
4  0.88    NA
5  0.86    NA
6  0.52    NA
7  0.35    NA
9    NA  0.71
10   NA  0.71
11   NA  0.69
12   NA  0.57
13   NA  0.55
14   NA  0.52
15   NA  0.40
16   NA -0.37
17   NA  0.37
18   NA  0.36
19   NA -0.34
20   NA -0.33
21   NA -0.32
8    NA    NA

该解决方案最终将用于10列以上的df,因此可扩展性是一个问题!

2 个答案:

答案 0 :(得分:1)

创建另外两个变量:一个用于指示x是否大于0.32,另一个包含值x(如果大于0.32)和y

ord1 <- apply(as.matrix(df),1,function(x) min(which(abs(x)>=0.32),ncol(df)))
ord2 <- df[cbind(1:nrow(df),ord1)]

df[order(ord1,-abs(ord2)),]
#        x     y
# 1   0.92  0.03
# 2   0.90 -0.01
# 3   0.90 -0.03
# 4   0.88  0.00
# 5   0.86  0.02
# 9   0.02  0.71
# 10 -0.03  0.71
# 11 -0.02  0.69
# 12 -0.06  0.57
# 13 -0.06  0.55
# 14 -0.01  0.52
# 15 -0.01  0.40
# 16  0.01 -0.37
# 17 -0.03  0.37
# 18 -0.03  0.36
# 19  0.01 -0.34
# 20  0.05 -0.33
# 21 -0.01 -0.32
# 7   0.35 -0.08
# 8   0.28  0.04
# 6   0.52  0.01

这可以推广到多个列,如下所示:

set.seed(123)
df <- data.frame(x1=runif(21,-1,1),
                 x2=runif(21,-1,1),
                 x3=runif(21,-1,1),
                 x4=runif(21,-1,1),
                 x5=runif(21,-1,1))

ord1 <- apply(as.matrix(df),1,function(x) min(which(abs(x)>=0.7),ncol(df)))
ord2 <- df[cbind(1:nrow(df),ord1)]

df[order(ord1,-abs(ord2)),]
#             x1          x2         x3          x4          x5
# 18 -0.91588093 -0.36363798 -0.2510744 -0.51276105 -0.33435292
# 11  0.91366669  0.80459809  0.5978497 -0.99875045 -0.35925352
# 20  0.90900730 -0.71439996 -0.8103187 -0.16470644  0.90894765
# 6  -0.90888700  0.08813205 -0.0680751  0.58868464 -0.64989470
# 5   0.88093457  0.41706094 -0.5339318  0.62477902  0.77293812
# 16  0.79964994  0.51691908  0.5066157 -0.29640418  0.02301092
# 15 -0.79415063 -0.04440806 -0.7449367  0.22554201 -0.06644192
# 8   0.78483809 -0.42168053  0.7156554  0.50895032  0.30620385
# 21  0.77907863 -0.17090733 -0.2320607  0.57639167 -0.03419521
# 4   0.76603481  0.31141160 -0.7223879  0.62012871  0.78610223
# 3  -0.18204616  0.98853955 -0.6951105 -0.10296732  0.96991396
# 14  0.14526680 -0.95077263 -0.5869372 -0.24036692 -0.81281003
# 10 -0.08677053  0.92604847 -0.1155999  0.42036480  0.31351626
# 9   0.10287003 -0.70577271 -0.9083377  0.25844226 -0.31296706
# 17 -0.50782453 -0.56718413  0.7900907 -0.77772915  0.19997792
# 12 -0.09333169  0.38141056 -0.7562015 -0.04936685 -0.62461776
# 1  -0.42484496  0.38560681 -0.1725513 -0.45123271 -0.79427071
# 7   0.05621098  0.18828404 -0.4680547 -0.12033662 -0.73860862
# 13  0.35514127  0.59093484  0.1218960 -0.55976223  0.56458860
# 2   0.57661027  0.28101363 -0.2623091  0.62928008 -0.13021452
# 19 -0.34415856 -0.53674843  0.3302304  0.33611117 -0.02277393

答案 1 :(得分:1)

我只想创建一个&#34; cutoff&#34;变量&gt;在截止变量&gt;处将数据帧分成两部分。 <重新排列独立数据帧>把他们重新绑回来。

<bean id="appContext" class="com.common.rest.AppContext" />