R 在一个数据帧中仅保留与ID对应的两行

R 在一个数据帧中仅保留与ID对应的两行,r,subset,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 事先非常感谢 一个选项是使用data.table 将“data.frame”转换为“data.table”

我有以下数据(这是一个模拟版本),我正在使用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

事先非常感谢

一个选项是使用
data.table

将“data.frame”转换为“data.table”(
setDT(df1)
)。按“ID”列分组,并根据逻辑条件对数据集进行子集。如果行数为1(
If(.N==1)
),我们取“m”的值,即每个组的唯一值或
其他
,我们将每个组的值与“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

一个选项是使用
data.table

将“data.frame”转换为“data.table”(
setDT(df1)
)。按“ID”列分组,并根据逻辑条件对数据集进行子集。如果行数为1(
If(.N==1)
),我们取“m”的值,即每个组的唯一值或
其他
,我们将每个组的值与“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

与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

与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

A
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

A
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

另一种
base R
方式是使用拆分、应用、组合样式过滤器:

`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

`rownames另一种
基本R
方式是使用拆分、应用、组合样式过滤器:

`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

`rownames一堆基本的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, ]

一组基本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, ]


好啊你的问题是什么?我希望你已经做了一些研究,至少对如何做到这一点有了一些想法。谢谢你的编辑,我只是在发帖后才意识到这个问题看起来很糟糕。至于我的问题,是的,我做了一些研究,但我只能够保持可以设置为特定字符串的值,我在ID中的最后一个值不同,我不知道如何保持这些值。谢谢。@akrun没问题。。事实上,我刚刚学习了
行数
功能!好啊你的问题是什么?我希望你已经做了一些研究,至少对如何做到这一点有了一些想法。谢谢你的编辑,我只是在发帖后才意识到这个问题看起来很糟糕。至于我的问题,是的,我做了一些研究,但我只能够保持可以设置为特定字符串的值,我在ID中的最后一个值不同,我不知道如何保持这些值。谢谢。@akrun没问题。。事实上,我刚刚学习了
行数
功能!很好,谢谢你。另外,我要特别感谢你没有对我最初对这个问题的糟糕编辑感到不满。@Pierrelaffortune你可以将其作为一个单独的答案发布。如果列没有排序,它不会给出不同的结果。i、 OP希望“m1”作为一个值。这是真的,我纠正了“m1”值错位的情况。这很有效,非常感谢。另外,我要特别感谢你没有对我最初对这个问题的糟糕编辑感到不满。@Pierrelaffortune你可以将其作为一个单独的答案发布。如果列没有排序,它不会给出不同的结果。i、 OP想要“m1”作为一个值。没错,我纠正了“m1”值放错位置的情况。@akrun我明白了。我试图解决这个问题。这也很有效,非常感谢。我会努力成为dplyr的专家,这看起来很直观而且非常有用。@Bogs修复Akrun是必要的。没有它,我仍在试图找出问题所在。我是一名非常新的R程序员,我从直觉上理解您对
dplyr
的看法,但当我更加熟练时,我会尝试学习
data.table
。@akrun我明白了。我试图解决这个问题。这也很有效,非常感谢。我会努力成为dplyr的专家,这看起来很直观而且非常有用。@Bogs修复Akrun是必要的。没有它,我仍在试图找出问题所在。我是一名非常新的R程序员,我从直觉上理解你对
dplyr
的看法,但当我更熟练时,我会尝试学习
数据表
。base R中的Meravigliose queste soluzioni。@SabDeM你知道我是意大利人吗,或者这只是巧合?:)这只是一个统计问题:我认为90%的你是意大利人,因为你叫“尼古拉”。@SabDeM你是对的!无论如何,非常感谢您的评论,非常感谢!R基地的Meravigliose queste soluzioni@SabDeM你知道我是意大利人吗,还是这只是巧合这只是一个统计问题:我认为90%的你是意大利人,因为你叫“尼古拉”。@SabDeM你是对的!无论如何,非常感谢您的评论,非常感谢!