Как ввести несколько пустых строк в DF на основе строки в столбце - PullRequest
3 голосов
/ 15 апреля 2019

У меня есть выходной df, в который я пытаюсь вставить пустые строки после каждой записи closing_bal в столбце с именем placement_status_type. Идея состоит в том, что после того, как я вставляю пустые строки, я сохраняю их в виде файла Excel, чтобы конечному пользователю было удобно читать числа в Excel.

Я знаю функцию add_row, но не могу найти способ использовать ее в условиях.

sample data:
df <- data.frame(stringsAsFactors=FALSE,
         placement_status_type = c("opening_bal", "New", "Transfer", "Reinstated",
                                   "Suspended", "Exit", "closing_bal",
                                   "opening_bal", "New", "Transfer", "Reinstated",
                                   "Suspended", "Exit", "closing_bal", "opening_bal",
                                   "New", "Transfer", "Exit", "closing_bal",
                                   "opening_bal", "New", "Exit", "closing_bal",
                                   "Transfer", "Exit", "closing_bal", "Transfer",
                                   "Suspended", "Exit", "closing_bal"),
                        Aug_18 = c(173, 11, -6, 16, -21, -9, 164, 5, 4, 0, 3, 0, -2,
                                   10, 17, 6, -1, -4, 18, -1, 0, 0, -1, 0, 0,
                                   0, 0, 0, 0, 0)
      )

Ответы [ 2 ]

5 голосов
/ 15 апреля 2019

add_row может добавлять только одну строку за раз. Мы можем разделить фрейм данных при каждом появлении «close_bal», а затем add_row для каждой группы.

library(tidyverse)

df %>%
   group_split(c(0, 
     cumsum(placement_status_type == "closing_bal")[-nrow(df)]), keep = FALSE) %>%
   map_dfr(~add_row(., placement_status_type = "", Aug_18 = 0))


# A tibble: 36 x 2
#   placement_status_type Aug_18
#   <chr>                  <dbl>
# 1 opening_bal              173
# 2 New                       11
# 3 Transfer                  -6
# 4 Reinstated                16
# 5 Suspended                -21
# 6 Exit                      -9
# 7 closing_bal              164
# 8 ""                         0
# 9 opening_bal                5
#10 New                        4
# … with 26 more rows

Аналогичным образом, мы также можем использовать do, если хотим избежать разделения и привязки строк к фрейму данных

df %>%
 group_by(group = c(0, 
         cumsum(placement_status_type == "closing_bal")[-nrow(df)])) %>%
 do(add_row(., placement_status_type = "", Aug_18 = 0)) %>%
 ungroup() %>%
 select(-group)

В качестве общего решения, если мы хотим добавить определенную строку несколько раз, мы можем создать ее как отдельную tibble

add_df <- tibble(placement_status_type = "", Aug_18 = 0)

и повторите это соответственно

n <- 3

df %>%
  group_split(c(0, 
   cumsum(placement_status_type == "closing_bal")[-nrow(df)]), keep = FALSE) %>%
   map_dfr(~bind_rows(., add_df[rep(seq_len(nrow(add_df)), n), ]))

С do это будет

df %>%
  group_by(group = c(0, 
    cumsum(placement_status_type == "closing_bal")[-nrow(df)])) %>%
  do(bind_rows(., add_df[rep(seq_len(nrow(add_df)), n), ])) %>%
  ungroup() %>%
  select(-group)

Все это также может быть достигнуто в базе R

do.call(rbind, lapply(split(df, 
  c(0, cumsum(df$placement_status_type == "closing_bal")[-nrow(df)])), function(x) 
   rbind(x, add_df[rep(seq_len(nrow(add_df)), n), ])))
1 голос
/ 15 апреля 2019

Поскольку add_row добавляет только по одной за раз, вы можете просто получить индексы строк конечного баланса и затем просмотреть их, просто учитывая количество ранее добавленных строк.

#get closing bal row numbers
foo <- which(df$placement_status_type == "closing_bal")

#iteratively add new row using add_row
# while accounting for previous rows
for(i in 1:length(foo))
  df <- tibble::add_row(df, placement_status_type = NA, Aug_18 = NA, .after = foo[i] + (i - 1))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...