我有以下数据(这是模拟版本),我正在使用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
非常感谢您提前。
答案 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, ]