Hai Misalkan saya memiliki data berikut

df <- data.frame(group = rep(c("group_1","group_2","group_3", "group_4", "group_5", "group_6"), each=3),
                 X = paste(letters[1:18]),
                 Y = c(1:18))

 df
     group X  Y
1  group_1 a  1
2  group_1 b  2
3  group_1 c  3
4  group_2 d  4
5  group_2 e  5
6  group_2 f  6
7  group_3 g  7
8  group_3 h  8
9  group_3 i  9
10 group_4 j 10
11 group_4 k 11
12 group_4 l 12
13 group_5 m 13
14 group_5 n 14
15 group_5 o 15
16 group_6 p 16
17 group_6 q 17
18 group_6 r 18

Yang saya inginkan adalah memasukkan 5 baris dengan nilai -10 di kolom Y tetapi mempertahankan ID grup

Saya mencoba melakukan ini berdasarkan cross post yang serupa tetapi tampaknya tidak dapat mempertahankan ID Grup dan ini sepertinya hanya berfungsi untuk memasukkan 1 baris.

> df %>%
+   group_split(group) %>% 
+   map_dfr(~ .x %>% 
+             add_row(Y = -10, .after = 0))
# A tibble: 24 x 3
   group   X         Y
   <chr>   <chr> <dbl>
 1 NA      NA      -10
 2 group_1 a         1
 3 group_1 b         2
 4 group_1 c         3
 5 NA      NA      -10
 6 group_2 d         4
 7 group_2 e         5
 8 group_2 f         6
 9 NA      NA      -10

Contoh di atas gagal karena hanya menyisipkan 1 baris apalagi ID grup adalah kehilangan, idealnya misalnya, harus ada 5 baris dengan grup_1 dimasukkan dengan nilai-Y -10.

Apakah ini mungkin? Terima kasih sebelumnya!

2
Ahdee 3 April 2021, 00:42

3 jawaban

Apakah Anda mencari solusi ini?

df1 <- df %>% 
  group_by(group) %>% 
  do({ df <- . 
  last_row           <- df %>% slice(n())
  last_row$Y  <- -10
  df                 <- bind_rows(df, last_row)
  })

Keluaran:

   group   X         Y
   <chr>   <chr> <dbl>
 1 group_1 a         1
 2 group_1 b         2
 3 group_1 c         3
 4 group_1 c       -10
 5 group_2 d         4
 6 group_2 e         5
 7 group_2 f         6
 8 group_2 f       -10
 9 group_3 g         7
10 group_3 h         8
11 group_3 i         9
12 group_3 i       -10
13 group_4 j        10
14 group_4 k        11
15 group_4 l        12
16 group_4 l       -10
17 group_5 m        13
18 group_5 n        14
19 group_5 o        15
20 group_5 o       -10
21 group_6 p        16
22 group_6 q        17
23 group_6 r        18
24 group_6 r       -10
1
TarJae 2 April 2021, 21:54

Opsi basis r menggunakan split + rbind

do.call(
  rbind,
  c(
    make.row.names = FALSE,
    lapply(
      split(df, df$group),
      function(x) {
        rbind(setNames(data.frame(NA, NA, -10), names(x)), x)
      }
    )
  )
)

Memberi

     group    X   Y
1     <NA> <NA> -10
2  group_1    a   1
3  group_1    b   2
4  group_1    c   3
5     <NA> <NA> -10
6  group_2    d   4
7  group_2    e   5
8  group_2    f   6
9     <NA> <NA> -10
10 group_3    g   7
11 group_3    h   8
12 group_3    i   9
13    <NA> <NA> -10
14 group_4    j  10
15 group_4    k  11
16 group_4    l  12
17    <NA> <NA> -10
18 group_5    m  13
19 group_5    n  14
20 group_5    o  15
21    <NA> <NA> -10
22 group_6    p  16
23 group_6    q  17
24 group_6    r  18
2
ThomasIsCoding 2 April 2021, 21:48

Kita bisa menambahkan uncount setelah add_row untuk mereplikasi baris pertama 5 kali

library(dplyr)
library(tidyr)
library(purrr)
library(tibble)
df %>% 
   group_split(group) %>% 
   map_dfr(~ .x %>% 
                add_row(group = first(.x$group), Y = -10, .after = 0) %>%
                uncount(rep(c(5, 1), c(1, n()-1))))

-keluaran

# A tibble: 48 x 3
#   group   X         Y
#   <chr>   <chr> <dbl>
# 1 group_1 <NA>    -10
# 2 group_1 <NA>    -10
# 3 group_1 <NA>    -10
# 4 group_1 <NA>    -10
# 5 group_1 <NA>    -10
# 6 group_1 a         1
# 7 group_1 b         2
# 8 group_1 c         3
# 9 group_2 <NA>    -10
#10 group_2 <NA>    -10
# … with 38 more rows

Atau karena jumlah kolom hanya 3, kita juga bisa melakukan ini di dplyr sendirian dengan summarise setelah pengelompokan oleh 'grup'. Dalam versi yang lebih baru dari dplyr, summarise tidak memiliki kendala untuk mengembalikan satu baris per grup

df %>%
    group_by(group) %>%
    summarise(X = c(rep(NA_character_, 5), X), 
              Y = c(rep(-10, 5), Y), .groups = 'drop')
# A tibble: 48 x 3
#   group   X         Y
#   <chr>   <chr> <dbl>
# 1 group_1 <NA>    -10
# 2 group_1 <NA>    -10
# 3 group_1 <NA>    -10
# 4 group_1 <NA>    -10
# 5 group_1 <NA>    -10
# 6 group_1 a         1
# 7 group_1 b         2
# 8 group_1 c         3
# 9 group_2 <NA>    -10
#10 group_2 <NA>    -10
# … with 38 more rows
3
akrun 2 April 2021, 21:53