【问题标题】:sort and number within levels of a factor in r在 r 中的一个因子的级别内排序和编号
【发布时间】:2012-04-26 07:42:31
【问题描述】:

如果我有以下数据框 G:

z    type   x   
1     a     4
2     a     5 
3     a     6
4     b     1
5     b     0.9
6     c     4

我想得到:

z    type   x   y
3     a     6   3
2     a     5   2
1     a     4   1
4     b     1   2
5     b     0.9 1
6     c     4   1

即我想根据向量x 在因子type 的级别内对整个数据框进行排序。获取每个级别的长度a = 3 b=2 c=1,然后在新向量y 中以递减的方式编号。

我目前的起点是sort()

tapply(y, x, sort)

最好先尝试使用 sapply 来拆分所有内容吗?

【问题讨论】:

    标签: r


    【解决方案1】:

    有很多方法可以给这只猫剥皮。这是一种使用基本 R 和向量化代码分两步的解决方案(没有任何 apply):

    1. 使用order和xtfrm对数据进行排序
    2. 使用rle 和sequence 生成序列。

    复制您的数据:

    dat <- read.table(text="
    z    type   x   
    1     a     4
    2     a     5 
    3     a     6
    4     b     1
    5     b     0.9
    6     c     4
    ", header=TRUE, stringsAsFactors=FALSE)
    

    两行代码:

    r <- dat[order(dat$type, -xtfrm(dat$x)), ]
    r$y <- sequence(rle(r$type)$lengths)
    

    结果:

    r
      z type   x y
    3 3    a 6.0 1
    2 2    a 5.0 2
    1 1    a 4.0 3
    4 4    b 1.0 1
    5 5    b 0.9 2
    6 6    c 4.0 1
    

    对order 的调用有点复杂。由于您要按升序对一列进行排序,然后按降序对第二列进行排序,因此请使用辅助函数 xtfrm。详情见?xtfrm,但在?order中也有描述。

    【讨论】:

    • 嘿,这两个很好的解决方案。我以前没见过 xtfrm。很有用。我希望x 中的最高数字具有最高的y,因此从xtfrm 中删除了-,这是一个完美的结果,谢谢
    • @Andrie 我也没有见过xtfrm,但并没有真正了解它的作用。它在这里做什么而负面不会做? [这个功能的帮助文件不是很好]
    • @user1322296 好的,在这种情况下,您根本不需要xtfrm - 它只会减慢速度。
    • @TylerRinker xtfrm 成语也适用于字符串,但在这种情况下你是对的,不需要它。
    【解决方案2】:

    我更喜欢安德烈:

    dat <- read.table(text="z    type   x   
    1     a     4
    2     a     5 
    3     a     6
    4     b     1
    5     b     0.9
    6     c     4", header=T)
    

    三行代码:

    dat <- dat[order(dat$type), ]
    x <- by(dat, dat$type, nrow)
    dat$y <- unlist(sapply(x, function(z) z:1))
    

    我编辑了我的回复以适应 Andrie 提到的 cmets。这行得通,但如果你走这条路而不是安德烈,那你就疯了。

    【讨论】:

    • 您需要将最后一个 rep(x,x) 替换为 seq_len(x) 然后它应该可以工作。很好的解决方案。
    • @Andrie,我认为它可以正常工作。第二行给出了每个因素的长度(你使用rle 的作用),即c(3, 2, 1)。然后我使用rep 重复每个长度该次数。试试运行看看。
    • 没关系,我误解了发帖人想要什么。我现在看到了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-12
    相关资源
    最近更新 更多