anderwyang
anderwyang

Reputation: 2411

Retrieve 'second to last' data of every group

I want to retrieve 'second to last' data of every group . Currently ,the code as below, using 'group_modify' twice. Is there any available function for this? (how to simply current code)? Thanks!

The wished result in the red rectangular in attached image.

library(dplyr)

test_data <- data.frame(category=c("a","a","c","a","b","c","a","b","c"),
                        value=c(1.72,0.32,0.22,1.29,-0.49,0.61,1.24,0.58,0.26))


test_data %>%  arrange(category ) %>% 
  group_by(category) %>% 
  group_modify(~tail(.x,2)) %>% 
  group_modify(~head(.x,1))

enter image description here

Upvotes: 2

Views: 723

Answers (3)

Ronak Shah
Ronak Shah

Reputation: 388817

You can extract n() - 1 row in each group.

library(dplyr)

test_data %>% group_by(category) %>% slice(n()-1) %>% ungroup

#  category value
#  <chr>    <dbl>
#1 a         1.29
#2 b        -0.49
#3 c         0.61

Upvotes: 3

TarJae
TarJae

Reputation: 78917

We could use nth(value, -2), which gives second last of each group:

library(dplyr)

  test_data %>%  
    arrange(category ) %>% 
    group_by(category) %>% 
    summarise(value1 = nth(value, -2))
  category value1
  <chr>     <dbl>
1 a          1.29
2 b         -0.49
3 c          0.61

Upvotes: 5

D.J
D.J

Reputation: 1304

If a list output is acceptable this works:

test_data %>% 
  arrange(category) %>% 
  group_split(category) %>% 
  map(. %>% slice(nrow(.)-1))

[[1]]
# A tibble: 1 x 2
  category value
  <chr>    <dbl>
1 a         1.29

[[2]]
# A tibble: 1 x 2
  category value
  <chr>    <dbl>
1 b        -0.49

[[3]]
# A tibble: 1 x 2
  category value
  <chr>    <dbl>
1 c         0.61

Upvotes: 1

Related Questions