Как вставить пустые строки в df на основе определенного значения - PullRequest
1 голос
/ 20 июня 2019

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

# This is part of the df that I have
df <- data.frame(stringsAsFactors=FALSE,
           referral_phase_code = c("-", "EA", "EA", "EA", "EA", "EA", "EA", "-", "-",
                                   "PPS", "PPS", "-", "OS", "-", "-", "EA",
                                   "EA", "EA", "EA", "EA", "EA", "-", "-", "PPS",
                                   "PPS", "-"),
         placement_status_type = c("opening_bal", "New", "Transfer", "Reinstated",
                                   "Suspended", "Trf to PPS", "Exit",
                                   "closing_bal", "opening_bal", "New", "Trf to EA",
                                   "closing_bal", "New", "closing_bal", "opening_bal",
                                   "New", "Transfer", "Reinstated", "Suspended",
                                   "Trf to PPS", "Exit", "closing_bal",
                                   "opening_bal", "New", "Trf to EA", "closing_bal")
      )

# This is the desired output
output_df <- data.frame(stringsAsFactors=FALSE,
                  referral_phase_code = c("-", "EA", "EA", "EA", "EA", "EA", "EA", "-", NA,
                                          "-", "PPS", "PPS", "-", NA, "OS",
                                          "-", NA, "-", "EA", "EA", "EA", "EA",
                                          "EA", "EA", "-", NA, "-", "PPS", "PPS",
                                          "-"),
                placement_status_type = c("opening_bal", "New", "Transfer", "Reinstated",
                                          "Suspended", "Trf to PPS", "Exit",
                                          "closing_bal", NA, "opening_bal", "New",
                                          "Trf to EA", "closing_bal", NA, "New",
                                          "closing_bal", NA, "opening_bal",
                                          "New", "Transfer", "Reinstated",
                                          "Suspended", "Trf to PPS", "Exit", "closing_bal",
                                          NA, "opening_bal", "New", "Trf to EA",
                                          "closing_bal")
             )

. Мне известна функция add_row, но в этом случае я не уверен, как ее использовать.

Есть идеи?

Ответы [ 2 ]

4 голосов
/ 20 июня 2019

Я думаю, что это прекрасная возможность для логики на основе последовательностей:

idx <- which(df$placement_status_type == "closing_bal")

df <- df[sort(c(sequence(nrow(df)),idx)),]
df[seq_along(idx) + idx,] <- NA
df

Определите строки, продублируйте их и заполните вновь созданные дубликаты NA

1 голос
/ 20 июня 2019

Опция будет add_row после split указанием набора данных на основе вхождения 'Closing_bal' в столбце 'location_status_type'

library(tidyverse)
df %>%
     group_split(grp = cumsum(lag(placement_status_type == "closing_bal",
                  default = TRUE)), keep = FALSE) %>% 
     map_df(~ 
            .x %>% 
               add_row(referral_phase_code = NA, 
            placement_status_type = NA, .after = nrow(.))) %>%
     slice(-n())
# A tibble: 30 x 2
#   referral_phase_code placement_status_type
#   <chr>               <chr>                
# 1 -                   opening_bal          
# 2 EA                  New                  
# 3 EA                  Transfer             
# 4 EA                  Reinstated           
# 5 EA                  Suspended            
# 6 EA                  Trf to PPS           
# 7 EA                  Exit                 
# 8 -                   closing_bal          
# 9 <NA>                <NA>                 
#10 -                   opening_bal          
# … with 20 more rows

Или другой вариант - uncount путем расширения строк и затем replace строк duplicated номеров строк с NA

df %>%
   mutate(n = (row_number() %in% which(placement_status_type == 
              'closing_bal')) + 1) %>% 
   uncount(n, .remove = FALSE) %>% 
   rownames_to_column('rn') %>%
   mutate_all(list(~ replace(., duplicated(str_remove(rn, 
        "\\.\\d+$")), NA))) %>% 
   slice(-n())

или с использованием data.table

library(data.table)
setDT(df)[,  grp := shift(cumsum(placement_status_type == 
     'closing_bal'), fill = 0)][, .SD[c(seq_len(.N), .N+1)], by = grp]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...