根据组内排名创建R-新变量

3

我有一个数据框(df),这只是一个示例:

group value condition   
1     12      1
1     14      1
1     18      1
1     10      0
1     7       1
2     12      1
2     9       0
2     12      1
2     16      1
2     15      0

即;
df<-data.frame(group=c(1,1,1,1,1,2,2,2,2,2), value=c(12,14,18,10,7,12,9,12,16,15), condition=c(1,1,1,0,1,1,0,1,1,0))

我希望创建三个名为“rank1”,“rank2”和“rank3”的新列,其中:
  • rank1 给出 "group"中最小的“value”
  • rank2 给出 "group"中第二小的“value”
  • rank3 给出 "group"中第三小的“value”
  • 在满足条件=1的值中
希望输出如下:
group rank1 rank2 ran3
1     7     12    14
2     12    12    16

我该如何使用R完成这个任务?非常感谢您的帮助。非常感谢。
3个回答

5
使用 data.table
library(data.table)
setDT(df)[condition == 1, 
          setNames(as.list(sort(value)[1:3]), paste0("rank", 1:3)), 
          by = group]
#    group rank1 rank2 rank3
# 1:     1     7    12    14
# 2:     2    12    12    16

@Josh O'Brien,我通过添加一个条件来编辑了这个问题。非常感谢。 - oercim

2

以下是一种使用 dplyr/tidyr 的方法:

 library(dplyr)
 library(tidyr)
 df %>% 
    group_by(group) %>% 
    filter(condition!=0)
    arrange(value) %>% 
    slice(1:3) %>%
    mutate(n=paste0('rank', row_number())) %>% 
    select(-condition) 
    spread(n, value)
#    group rank1 rank2 rank3
#1     1     7    12    14
#2     2    12    12    16

或使用data.table

的方式。

 library(data.table)
 dcast.data.table(setkey(setDT(df), value)[condition!=0, 
     list(rank=paste0('rank', 1:3), value[1:3]), group], 
           group~rank, value.var='V2')
 #   group rank1 rank2 rank3
 #1:     1     7    12    14
 #2:     2    12    12    16

或者使用基础的R语言。
 df1 <-  subset(df[order(df$value),], condition!=0  , select=1:2)
 df2 <- subset(transform(df1, .id=ave(group, group, FUN=seq_along)), .id<4)
 reshape(df2, idvar='group', timevar='.id', direction='wide')
 #  group value.1 value.2 value.3
 #5     1       7      12      14
 #6     2      12      12      16

我通过添加一个条件来编辑了这个问题。非常感谢。 - oercim
我使用了data.table。它运行得非常好。再次感谢。我很感激。 - oercim

1

又一个关于dplyr的答案...

myData <- read.csv(text=" group,value    
1,12
1,14
1,18
1,10
1,7
2,12
2,9
2,12
2,16 ")

library(dplyr)
myData %>% filter(condition==1) %>% group_by(group) %>% summarise(rank1=nth(sort(value),1),
                                        rank2=nth(sort(value),2),
                                        rank3=nth(sort(value),3))

我通过添加一个条件来编辑了这个问题。非常感谢。 - oercim
添加了来自dplyr的filter()函数。 - Jthorpe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接