为了账号安全,请及时绑定邮箱和手机立即绑定

如何在数据框中的分组变量中选择第一行和最后一行?

如何在数据框中的分组变量中选择第一行和最后一行?

Qyouu 2019-09-24 15:23:50
如何id在以下数据框中为每个唯一选择第一行和最后一行?tmp <- structure(list(id = c(15L, 15L, 15L, 15L, 21L, 21L, 22L, 22L, 22L, 23L, 23L, 23L, 24L, 24L, 24L, 24L), d = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), gr = c(2L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 2L, 1L, 1L, 2L, 1L, 1L, 1L, 2L), mm = c(3.4, 4.9, 4.4, 5.5, 4, 3.8, 4, 4.9, 4.6, 2.7, 4, 3, 3, 2, 4, 2), area = c(1L, 2L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 2L, 3L)), .Names = c("id", "d", "gr", "mm", "area"), class = "data.frame", row.names = c(NA, -16L))tmp#>    id d gr  mm area#> 1  15 1  2 3.4    1#> 2  15 1  1 4.9    2#> 3  15 1  1 4.4    1#> 4  15 1  1 5.5    2#> 5  21 1  1 4.0    2#> 6  21 1  2 3.8    2#> 7  22 1  1 4.0    2#> 8  22 1  1 4.9    2#> 9  22 1  2 4.6    2#> 10 23 1  1 2.7    2#> 11 23 1  1 4.0    2#> 12 23 1  2 3.0    2#> 13 24 1  1 3.0    2#> 14 24 1  1 2.0    3#> 15 24 1  1 4.0    2#> 16 24 1  2 2.0    3
查看完整描述

3 回答

?
心有法竹

TA贡献1866条经验 获得超5个赞

一个plyr解决方案(tmp是您的数据框):


library("plyr")

ddply(tmp, .(id), function(x) x[c(1, nrow(x)), ])

#    id d gr  mm area

# 1  15 1  2 3.4    1

# 2  15 1  1 5.5    2

# 3  21 1  1 4.0    2

# 4  21 1  2 3.8    2

# 5  22 1  1 4.0    2

# 6  22 1  2 4.6    2

# 7  23 1  1 2.7    2

# 8  23 1  2 3.0    2

# 9  24 1  1 3.0    2

# 10 24 1  2 2.0    3

或使用dplyr(另请参见此处):


library("dplyr")

tmp %>%

group_by(id) %>%

slice(c(1, n())) %>%

ungroup()

# # A tibble: 10 × 5

#       id     d    gr    mm  area

#    <int> <int> <int> <dbl> <int>

# 1     15     1     2   3.4     1

# 2     15     1     1   5.5     2

# 3     21     1     1   4.0     2

# 4     21     1     2   3.8     2

# 5     22     1     1   4.0     2

# 6     22     1     2   4.6     2

# 7     23     1     1   2.7     2

# 8     23     1     2   3.0     2

# 9     24     1     1   3.0     2

# 10    24     1     2   2.0     3


查看完整回答
反对 回复 2019-09-24
?
千万里不及你

TA贡献1784条经验 获得超9个赞

这是base中的解决方案R。如果有多个相同的组,则id此代码返回每个单独组的第一行和最后一行。

该解决方案可能比下面的其他答案更直观:

lmy.df = read.table(text = '

     id    d    gr     mm  area

     15    1     2   3.40     1

     15    1     1   4.90     2

     15    1     1   4.40     1

     15    1     1   5.50     2

     21    1     1   4.00     2

     21    1     2   3.80     2

     22    1     1   4.00     2

     23    1     1   2.70     2

     23    1     1   4.00     2

     23    1     2   3.00     2

     24    1     1   3.00     2

     24    1     1   2.00     3

     24    1     1   4.00     2

     24    1     2   2.00     3

', header = TRUE)


head <- aggregate(lmy.df, by=list(lmy.df$id), FUN = function(x) { first = head(x,1) } )

tail <- aggregate(lmy.df, by=list(lmy.df$id), FUN = function(x) {  last = tail(x,1) } )

head$order = 'first'

tail$order = 'last'


my.output <- rbind(head, tail)

my.output

#   Group.1 id d gr  mm area order

#1       15 15 1  2 3.4    1 first

#2       21 21 1  1 4.0    2 first

#3       22 22 1  1 4.0    2 first

#4       23 23 1  1 2.7    2 first

#5       24 24 1  1 3.0    2 first

#6       15 15 1  1 5.5    2  last

#7       21 21 1  2 3.8    2  last

#8       22 22 1  1 4.0    2  last

#9       23 23 1  2 3.0    2  last

#10      24 24 1  2 2.0    3  last


自发布我的原始答案以来,我已经知道使用它lapply比更好apply。这是因为apply如果每个组具有相同的行数,则不起作用。请参阅此处:按组编号行时出错


lmy.df = read.table(text = '

     id    d    gr     mm  area

     15    1     2   3.40     1

     15    1     1   4.90     2

     15    1     1   4.40     1

     15    1     1   5.50     2

     21    1     1   4.00     2

     21    1     2   3.80     2

     22    1     1   4.00     2

     23    1     1   2.70     2

     23    1     1   4.00     2

     23    1     2   3.00     2

     24    1     1   3.00     2

     24    1     1   2.00     3

     24    1     1   4.00     2

     24    1     2   2.00     3

', header = TRUE)



lmy.seq <- rle(lmy.df$id)$lengths

lmy.df$first <- unlist(lapply(lmy.seq, function(x) seq(1,x)))

lmy.df$last  <- unlist(lapply(lmy.seq, function(x) seq(x,1,-1)))

lmy.df


lmy.df2 <- lmy.df[lmy.df$first==1 | lmy.df$last == 1,]

lmy.df2


#   id d gr  mm area first last

#1  15 1  2 3.4    1     1    4

#4  15 1  1 5.5    2     4    1

#5  21 1  1 4.0    2     1    2

#6  21 1  2 3.8    2     2    1

#7  22 1  1 4.0    2     1    1

#8  23 1  1 2.7    2     1    3

#10 23 1  2 3.0    2     3    1

#11 24 1  1 3.0    2     1    4

#14 24 1  2 2.0    3     4    1

这是一个示例,其中每个组都有两行:


lmy.df = read.table(text = '

     id    d    gr     mm  area

     15    1     2   3.40     1

     15    1     1   4.90     2

     21    1     1   4.00     2

     21    1     2   3.80     2

     22    1     1   4.00     2

     22    1     1   6.00     2

     23    1     1   2.70     2

     23    1     2   3.00     2

     24    1     1   3.00     2

     24    1     2   2.00     3

', header = TRUE)


lmy.seq <- rle(lmy.df$id)$lengths


lmy.df$first <- unlist(lapply(lmy.seq, function(x) seq(1,x)))

lmy.df$last  <- unlist(lapply(lmy.seq, function(x) seq(x,1,-1)))

lmy.df


lmy.df2 <- lmy.df[lmy.df$first==1 | lmy.df$last == 1,]

lmy.df2


#   id d gr  mm area first last

#1  15 1  2 3.4    1     1    2

#2  15 1  1 4.9    2     2    1

#3  21 1  1 4.0    2     1    2

#4  21 1  2 3.8    2     2    1

#5  22 1  1 4.0    2     1    2

#6  22 1  1 6.0    2     2    1

#7  23 1  1 2.7    2     1    2

#8  23 1  2 3.0    2     2    1

#9  24 1  1 3.0    2     1    2

#10 24 1  2 2.0    3     2    1

原始答案:


my.seq <- data.frame(rle(my.df$id)$lengths)


my.df$first <- unlist(apply(my.seq, 1, function(x) seq(1,x)))

my.df$last  <- unlist(apply(my.seq, 1, function(x) seq(x,1,-1)))


my.df2 <- my.df[my.df$first==1 | my.df$last == 1,]

my.df2


   id d gr  mm area first last

1  15 1  2 3.4    1     1    4

4  15 1  1 5.5    2     4    1

5  21 1  1 4.0    2     1    2

6  21 1  2 3.8    2     2    1

7  22 1  1 4.0    2     1    3

9  22 1  2 4.6    2     3    1

10 23 1  1 2.7    2     1    3

12 23 1  2 3.0    2     3    1

13 24 1  1 3.0    2     1    4

16 24 1  2 2.0    3     4    1


查看完整回答
反对 回复 2019-09-24
  • 3 回答
  • 0 关注
  • 1321 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信