仅保留与数据框中的ID对应的两行

时间:2015-07-30 14:54:03

标签: r subset

我有以下数据(这是模拟版本),我正在使用R.

ID m
1  m1
1  m2
1  m3
2  m1
2  m2
3  m1
3  m2
3  m3
3  m4
4  m1

每个ID都有一个m1行,其余的m在ID中是可变长度的。我想保留m1值和每个ID对应的最后一个值。理想的输出看起来像这样:

ID m
1  m1
1  m3
2  m1
2  m2
3  m1
3  m4
4  m1

非常感谢您提前。

5 个答案:

答案 0 :(得分:5)

一种选择是使用data.table

转换' data.frame'到' data.table' (setDT(df1))。按ID'分组列,并基于逻辑条件,我们对数据集进行子集化。如果行数为1(if(.N==1)),我们将采用' m'即。每组唯一的价值或else,我们与“' m1' (m[m=='m1'])以及' m'的最后一个值每组(m[.N]

library(data.table)
setDT(df1)[, list(m=if(.N==1) m else c(m[m=='m1'], m[.N])), by = ID]
#   ID  m
#1:  1 m1
#2:  1 m3
#3:  2 m1
#4:  2 m2
#5:  3 m1
#6:  3 m4
#7:  4 m1

答案 1 :(得分:5)

base R解决方案:

df[ave(logical(nrow(df)),df$ID,FUN=function(x) seq_along(x) %in% c(1,length(x))),]
#   ID  m
#1   1 m1
#3   1 m3
#4   2 m1
#5   2 m2
#6   3 m1
#9   3 m4
#10  4 m1

答案 2 :(得分:4)

另一种base R方式是使用split,apply,combine样式过滤器:

`rownames<-`(do.call(rbind, lapply(split(df,df$ID), function(x) {
  x[x$m=="m1"|seq(nrow(x))==nrow(x),]})),NULL)
#   ID  m
# 1  1 m1
# 2  1 m3
# 3  2 m1
# 4  2 m2
# 5  3 m1
# 6  3 m4
# 7  4 m1

该功能的核心是x[x$m=="m1"|seq(nrow(x))==nrow(x),]。每个组由列“m”值子集,其等于“m1”或者是最后一行。根据需要,所有中间行都将被省略。 split(df,df$ID)按ID拆分数据框。 do.call(rbind..将所有内容重新组合到一个数据框中。 'rownames<-'...,NULL)使行号均匀。

答案 3 :(得分:3)

dplyr相同的结果:

df %>% 
   group_by(ID) %>%
   filter(row_number()==n()|m=='m1')


Source: local data frame [7 x 2]
Groups: ID

  ID  m
1  1 m1
2  1 m3
3  2 m1
4  2 m2
5  3 m1
6  3 m4
7  4 m1

答案 4 :(得分:3)

一堆基础R一个衬垫:

x[c(diff(x$ID),1) == 1 | c(1,diff(x$ID)) == 1, ]
x[(c(diff(x$ID),1) + c(1,diff(x$ID))) == 1, ]
x[x$m == 'm1' | c((x$m == 'm1')[-1],TRUE), ]
x[pmax(x$m == 'm1',c((x$m == 'm1')[-1],1)) == 1, ]