在R

时间:2019-11-27 22:11:16

标签: r subset

我有一个看起来像这样的数据集

id     year
 1     2012
 1     2014
 1     2015
 2     2014
 2     2018
 2     2019
 3     2011
 4     2010

我只想根据这两个条件(1)每个ID保留一次观察,(2)该ID的最近年份。因此,例如,对于ID 1,我只想要2015年行,对于ID 2,我只想要2019年行,对于ID 3和4,在那两年中我只有一个观察值,因此只需将它们都保留。

我尝试了一些不同的事情,例如:

df1<-subset(df, interaction(df$id, max(df$year)))

我知道这个子集没有意义,但我只是在编造东西,希望某些东西对我有意义。我尝试过的另一个

lapply(unique(df$id), function(max) subset(df, mac(year)))

但是我不断出错。

任何帮助将不胜感激!先感谢您。

3 个答案:

答案 0 :(得分:1)

您应该分组然后过滤

df %>%
  group_by(id) %>%
  filter(year == max(year)) %>%
  ungroup()

与@akrun提出的带有切片的解决方案不同,这将返回所有年份,其中每一年都是每个id的最大值。这取决于您的需求。

答案 1 :(得分:0)

通过'id'分组后,我们可以slicemax的行

library(dplyr)
df %>% 
    group_by(id) %>%
    slice(which.max(year))
# A tibble: 4 x 2
# Groups:   id [4]
#     id  year
#  <int> <int>
#1     1  2015
#2     2  2019
#3     3  2011
#4     4  2010

如果仅有这些列,则按“ id”分组后,将{year上的max应用于summarise

df %>%
     group_by(id) %>%
     summarise(year = max(year))

或与base R

aggregate(year ~ id, df, FUN = max)

数据

df <- structure(list(id = c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 4L), year = c(2012L, 
2014L, 2015L, 2014L, 2018L, 2019L, 2011L, 2010L)),
class = "data.frame", row.names = c(NA, 
-8L))

答案 2 :(得分:0)

1)子集/重复项使用在末尾的注释中可重复显示的df,并假设它在year中按id排序(即问题中显示的数据的大小写),将subsetduplicated一起使用。不使用任何软件包。

subset(df, !duplicated(id, fromLast = TRUE))
##   id year
## 3  1 2015
## 6  2 2019
## 7  3 2011
## 8  4 2010

2)子集/平均使用subset的另一种方法是使用ave。这不取决于要排序的输入。

subset(df, ave(year, id, FUN = max) == year)
##   id year
## 3  1 2015
## 6  2 2019
## 7  3 2011
## 8  4 2010

3)by b另一种基本方法是使用by。它返回我们rbind在一起的数据帧列表。

do.call("rbind", by(df, df$id, function(x) x[which.max(x$year), ]))
##   id year
## 1  1 2015
## 2  2 2019
## 3  3 2011
## 4  4 2010

4)轻触如果可以返回{name}为ID的年份向量,则可以使用tapply。同样,这仅使用基数R。

with(df, tapply(year,  id, max))
##    1    2    3    4 
## 2015 2019 2011 2010 

我也曾建议使用aggregate,但另一个响应者也提供了该答案。

注意

Lines <- "id     year
 1     2012
 1     2014
 1     2015
 2     2014
 2     2018
 2     2019
 3     2011
 4     2010"
df <- read.table(text = Lines, header = TRUE)