【问题标题】:R: split data based on a factor, add a ranking column and extractR:根据因子拆分数据,添加排名列并提取
【发布时间】:2015-06-29 14:49:31
【问题描述】:

我仍然无法知道如何访问拆分数据的不同元素。这是我的问题: 我有一个数据集,我想根据一列(状态)进行拆分。我想为每个子集添加一个排名列到我的数据中。这是我正在编写的函数的一部分。 我的数据集有 2 列,医院、状态、结果。对于每个州,我想添加一个“排名”列,根据结果对数据进行排名;结果最低的将排名第一,最高的结果将排名最后。

如何使用 split、sapply/lapply 来执行此操作?有没有更好的方法,比如使用“安排”? 我的主要问题是,当我使用这两种方法中的任何一种时,我都不知道如何访问拆分或排列数据的每个元素。 这是我的数据集的样子: 医院状态结果。行线在这里并不重要。

                           Hospital State Outcome 
 1 SOUTHEAST ALABAMA MEDICAL CENTER    AL    14.3
 2    MARSHALL MEDICAL CENTER SOUTH    AL    18.5
 3   ELIZA COFFEE MEMORIAL HOSPITAL    TX    18.1
 7                ST VINCENT'S EAST    TX    17.7
 8   DEKALB REGIONAL MEDICAL CENTER    AL    18.0
 9    SHELBY BAPTIST MEDICAL CENTER    AL    15.9

期望的结果是

                           Hospital State Outcome Rank
 1 SOUTHEAST ALABAMA MEDICAL CENTER    AL    14.3    1
 2 SHELBY BAPTIST MEDICAL CENTER       AL    15.9    2
 3 DEKALB REGIONAL MEDICAL CENTER      AL    18.0    3               
 4 MARSHALL MEDICAL CENTER SOUTH       AL    18.5    4 
 5 ST VINCENT'S EAST                   TX    17.7    1 
 6 ELIZA COFFEE MEMORIAL HOSPITAL      TX    18.1    2 

提前致谢。

【问题讨论】:

  • 我不知道您所说的“我不知道如何访问”是什么意思。有许多方法可以对数据框的行和列进行子集化和访问(我假设您正在将其读入数据框)。也许如果你举一个你期望看到的例子。
  • 也许您希望按州等汇总数据?然后你想看看 ddply 包或类似的东西。
  • 对。那只是我数据的一个样本,而且恰好都处于一个状态。我在帖子中对此进行了更改,以便您更好地了解它是什么。
  • @MikeWise 我的意思是,当我在此示例中基于状态拆分数据集并将其命名为 s 时,s[1] 将显示与第一个“状态”相关的所有行.我不知道如何在每个数据集中提取不同的行甚至一行的不同列。因此,如果 s[1] 有 50 行来自纽约,s[2] 有 32 行来自 WY,我不知道如何访问每个子集中的各个行,假设 s[1] 中的第 i 行。
  • @AsiehHarati 我认为迈克关于“访问”的问题是基于您所说的含糊不清。 split 是一个 R 函数,我们不知道你是指它还是只是某种子集...如果 s=split(DF,DF$state),你会指 s[[1]] 而不是 s[1],例如。

标签: r


【解决方案1】:

dplyr 包为此类问题提供了一个非常优雅的解决方案。我以mtcars 数据为例:

library(dplyr)

mtcars %>%
  group_by(cyl) %>%
  mutate(rank = row_number(mpg))

【讨论】:

    【解决方案2】:

    由于字符串变量中的所有空格,OP 的示例很难读入 R。

    这是一个更简单的例子:

    set.seed(1)
    DF <- data.frame(id=rep(1:2,sample(5,2))); DF$v <- runif(nrow(DF))*100
    #   id        v
    # 1  A 57.28534
    # 2  A 90.82078
    # 3  B 20.16819
    # 4  B 89.83897
    # 5  B 94.46753
    # 6  B 66.07978
    # 7  B 62.91140
    

    这是一个不使用任何包的解决方案:

    DF$r <- ave(DF$v,DF$id,FUN=rank)
    #   id        v r
    # 1  A 57.28534 1
    # 2  A 90.82078 2
    # 3  B 20.16819 1
    # 4  B 89.83897 4
    # 5  B 94.46753 5
    # 6  B 66.07978 3
    # 7  B 62.91140 2
    

    最后,按州内排名进行排序:

    DF[order(DF$id,DF$r),]
    #   id        v r
    # 1  A 57.28534 1
    # 2  A 90.82078 2
    # 3  B 20.16819 1
    # 7  B 62.91140 2
    # 6  B 66.07978 3
    # 4  B 89.83897 4
    # 5  B 94.46753 5
    

    如果您要排名的列中存在平局,请阅读rank 的文档并决定您希望如何处理平局。 dplyrdata.table 包(在其他答案中提到)也有很好的处理关系的功能,比如“dense rank”的概念。

    【讨论】:

    • @User7598 感谢您的加入。
    【解决方案3】:

    你可以试试这个

    library(data.table)
    setDT(dat)[, myrank := rank(Outcome), by = State]
    dat[,.SD[order(myrank)], by=State]
    
    #      State                         Hospital Outcome myrank
    #1:    AL SOUTHEAST ALABAMA MEDICAL CENTER    14.3      1
    #2:    AL    SHELBY BAPTIST MEDICAL CENTER    15.9      2
    #3:    AL   DEKALB REGIONAL MEDICAL CENTER    18.0      3
    #4:    AL    MARSHALL MEDICAL CENTER SOUTH    18.5      4
    #5:    TX                  ST VINCENT EAST    17.7      1
    #6:    TX   ELIZA COFFEE MEMORIAL HOSPITAL    18.1      2
    

    或使用ddply

    library(plyr)
    ddply(dat, .(State), function(x){x$myrank = rank(x$Outcome); x[order(x$myrank),]})
    
    #                          Hospital State Outcome myrank
    #1 SOUTHEAST ALABAMA MEDICAL CENTER    AL    14.3      1
    #2    SHELBY BAPTIST MEDICAL CENTER    AL    15.9      2
    #3   DEKALB REGIONAL MEDICAL CENTER    AL    18.0      3
    #4    MARSHALL MEDICAL CENTER SOUTH    AL    18.5      4
    #5                  ST VINCENT EAST    TX    17.7      1
    #6   ELIZA COFFEE MEMORIAL HOSPITAL    TX    18.1      2
    

    【讨论】:

    • 感谢指正。现在可以了。但是你能告诉我 [,.SD 是什么意思吗?我在帮助中找不到它。另外,:= 运算符是什么?
    • @AsiehHarati .SD 代表data.table的子集
    • @AsiehHarati := 被称为set,这里设置一个新列为myrank
    • @AsiehHarati 使用 [ 访问行和列与 data.table 不同。必须像DT[,2,with=FALSE] 一样访问列。要使用这个包,必须学习一点新语法。帮助页面在这里:github.com/Rdatatable/data.table/wiki/Getting-started
    • @Veerndra Gadekar,非常感谢您的帮助。 ddply 工作得很好。 :)
    【解决方案4】:

    你可以使用by

    do.call(
        rbind, 
        by(d, list(State = d$State), function(x) { x$Rank <- order(x$Outcome); x[order(x$Rank), ] }))
    

    d 是您的原始数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-19
      • 1970-01-01
      • 2016-03-06
      • 1970-01-01
      • 2019-07-30
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      相关资源
      最近更新 更多