首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >根据一个或多个其他列中的值对因子进行排序

根据一个或多个其他列中的值对因子进行排序
EN

Stack Overflow用户
提问于 2012-05-26 00:37:41
回答 4查看 38.6K关注 0票数 43

我查阅了许多关于排序因子的帖子,但还没有完全找到与我的问题相匹配的。不幸的是,我对R的了解还很基础。

我有一个我正在使用的考古文物目录的子集。我正在尝试交叉建立诊断历史工件类型和现场测试位置的表格。使用ddply或tapply很容易。

我的问题是,我希望根据平均诊断日期(数字/年)对工件类型(一个因子)进行排序,并且一直按字母顺序进行排序。我知道我需要使它成为一个有序因子,但是我不知道如何根据其他列中的年值对它进行排序。

代码语言:javascript
复制
IDENTIFY                                      MIDDATE
engine-turned fine red stoneware              1769
white salt-glazed stoneware, scratch blue     1760
wrought nail, 'L' head                        1760
yellow lead-glazed buff earthenware           1732
...

需要排序的内容:

代码语言:javascript
复制
IDENTIFY                                      MIDDATE
yellow lead-glazed buff earthenware           1732
white salt-glazed stoneware, scratch blue     1760
wrought nail, 'L' head                        1760
engine-turned fine red stoneware              1769
...

因子(IDENTIFY)需要按日期(MIDDATE)排序。我以为我已经有了

代码语言:javascript
复制
Catalog$IDENTIFY<-factor(Catalog$IDENTIFY,levels=Catalog$MIDDATE,ordered=TRUE)

但是得到警告:

代码语言:javascript
复制
In `levels<-`(`*tmp*`, value = if (nl == nL) as.character(labels) 
else paste0(labels,: duplicated levels will not be allowed 
in factors anymore

IDENTIFY有大约130个因子级别,其中许多具有相同的MIDDATE值,因此我需要按MIDDATE和另一个列TYPENAME对IDENTIFY进行排序。

更多细节:

我有一个数据帧Catalog,它分解(即str(Catalog))为:

代码语言:javascript
复制
> str(Catalog)
'data.frame':   2211 obs. of  15 variables:
 $ TRENCH  : Factor w/ 7 levels "DRT 1","DRT 2",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ U_TYPE  : Factor w/ 3 levels "EU","INC","STP": 1 1 1 1 1 1 1 1 1 1 ...
 $ U_LBL   : Factor w/ 165 levels "001","005","007",..: 72 72 72 72 72 72 ...
 $ L_STRAT : Factor w/ 217 levels "#2-7/25","[3]",..: 4 4 4 4 4 4 89 89 89 89 ...
 $ START   : num  0 0 0 0 0 0 39.4 39.4 39.4 39.4 ...
 $ END     : num  39.4 39.4 39.4 39.4 39.4 39.4 43.2 43.2 43.2 43.2 ...
 $ Qty     : int  1 1 3 5 1 1 6 8 1 1 ...
 $ MATNAME : Factor w/ 6 levels "Ceramics","Chipped Stone",..: 1 1 1 5 5 6 ...
 $ TYPENAME: Factor w/ 9 levels "Architectural Hardware",..: 9 9 9 1 1 3 9 ...
 $ CATNAME : Factor w/ 32 levels "Biface","Bottle Glass",..: 24 29 29 6 24 ...
 $ IDENTIFY: Factor w/ 112 levels "amethyst bottle glass",..: 17 91 96 71 103 ...
 $ BEGDATE : int  1820 1820 1830 1835 1700 NA 1670 1762 1800 1720 ...
 $ ENDDATE : int  1900 1970 1860 1875 1820 NA 1795 1820 1820 1780 ...
 $ OCC_LBL : Ord.factor w/ 5 levels "Late 19th Century"<..: 2 1 2 2 4 5 4 3 ...
 $ MIDDATE : num  1860 1895 1845 1855 1760 ...

我需要将IDENTIFY设置为有序因子,并按MIDDATE -> TYPENAME -> alpha by IDENTIFY进行重新排序。

我真正不明白的是如何根据多列的组合顺序进行重新排序。

我只会在数据库中这样做,但我运行的很多东西都是各种交叉表中的加权平均值(例如,按位置对工件类在地面以下的加权平均深度)……

Access中的...doable,但混乱且不可预测。在R中管理要容易得多,也更整洁,但我不希望手动对结果表进行重新排序。

我试着按照这些思路来做一些事情:

代码语言:javascript
复制
>xtab.Catalog<-tapply(Catalog$Qty,list(Catalog$IDENTIFY,Catalog$TRENCH),sum)

IDENTIFY                        DRT1    DRT2    DRT3    DRT4    DRT5    DRT6
Staffordshire stoneware         4       NA      NA      NA      NA      NA  
undecorated delftware           6       4       NA      NA      NA      NA  
unidentified wrought nail       15      9       3       1       3       NA  
white salt-glazed stoneware     6       1       1       NA      2       1   
white salt-glazed scratch blue  1       NA      NA      NA      NA      NA  
white stoneware, slip-dipped    NA      NA      NA      NA      NA      NA  
wrought nail, 'L' head          2       NA      NA      NA      NA      NA  
wrought nail, 'rose' head       62      21      4       NA      1       1   
wrought nail, 'T' head          2       NA      1       NA      NA      1   
yellow lead-glazed              12      NA      NA      NA      1       3   
...

...but我需要它们按逻辑(即按时间/类型)排序,而不是按字母顺序排序。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-05-28 09:01:59

这是一个可重现的样本,并提供了解决方案:

代码语言:javascript
复制
set.seed(0)
a = sample(1:20,replace=F)
b = sample(1:20,replace=F)
f = as.factor(letters[1:20])

> a
 [1] 18  6  7 10 15  4 13 14  8 20  1  2  9  5  3 16 12 19 11 17
> b
 [1] 16 18  4 12  3  5  6  1 15 10 19 17  9 11  2  8 20  7 13 14
> f
 [1] a b c d e f g h i j k l m n o p q r s t
Levels: a b c d e f g h i j k l m n o p q r s t

现在来看新的因素:

代码语言:javascript
复制
fn = factor(f, levels=unique(f[order(a,b,f)]), ordered=TRUE)

> fn
 [1] a b c d e f g h i j k l m n o p q r s t
20 Levels: k < l < o < f < n < b < c < i < m < d < s < q < g < h < e < ... < j

按'a‘、下一个'b’和最后的'f‘本身排序(尽管在本例中,'a’没有重复值)。

票数 46
EN

Stack Overflow用户

发布于 2016-07-29 23:59:41

我推荐以下基于dplyr的方法(h/t daattali),它可以扩展到任意多个列:

代码语言:javascript
复制
library(dplyr)
Catalog <- Catalog %>%
  arrange(MIDDATE, TYPENAME) %>%               # sort your dataframe
  mutate(IDENTIFY = factor(IDENTIFY, unique(IDENTIFY))) # reset your factor-column based on that order
票数 31
EN

Stack Overflow用户

发布于 2020-03-10 23:57:02

函数fct_reorder2就是这样做的。

请注意fct_reorder按升序排序而fct_reordering2按降序排序的微妙之处。

文档中的代码:

代码语言:javascript
复制
df0 <- tibble::tribble(
  ~color,     ~a, ~b,
  "blue",      1,  2,
  "green",     6,  2,
  "purple",    3,  3,
  "red",       2,  3,
  "yellow",    5,  1

)

代码语言:javascript
复制
df0$color <- factor(df0$color)
fct_reorder(df0$color, df0$a, min)
 #> [1] blue   green  purple red    yellow
 #> Levels: blue red purple yellow green
fct_reorder2(df0$color, df0$a, df0$b)
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10758243

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档