簡體   English   中英

R:基於因子拆分數據,添加排名列並提取

[英]R: split data based on a factor, add a ranking column and extract

我仍然無法知道如何訪問拆分數據的不同元素。 這是我的問題:我有一個數據集,我想根據列(State)進行拆分。 我希望為每個子集的數據添加一個排名列。 這是我正在編寫的函數的一部分。 我的數據集有2列,醫院,州,結果。 對於每個州,我想添加一個“排名”列,根據結果對數據進行排名; 最低結果將排名第1,最高結果將排在最后。

我怎樣才能使用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 

提前致謝。

由於字符串變量中的所有空格,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包(在其他答案中提到)也有很好的處理關系的功能,比如“ 密集排名 ”的概念。

dplyr軟件包為這類問題提供了非常優雅的解決方案。 我正在使用mtcars數據作為示例:

library(dplyr)

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

你可以試試這個

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

您可以使用by

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

其中d是您的原始數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM