вставлять новые строки условно и добавлять значения в новые строки в R - PullRequest
1 голос
/ 25 апреля 2020

У меня есть фрейм данных и вектор только с двумя числами: 201 и 200.

type <- c(222, 222, 199, 251, 106, 88, 88, 88, 88, 61, 199, 251)
latency <- c(4167, 4433, 5109, 5635, 6618, 6980, 7246, 7512, 7778, 8045, 8311, 8577)
urevent <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)

acc <- c(201, 200)

df1 = data.frame(type, latency, urevent)

Мне нужно добавить значения из acc в столбец type, под каждый экземпляр df1$type == 199, последовательно. В acc есть равное количество экземпляров 199 и чисел.

latency следует скопировать из строки выше и добавить 50 к ней. urevent в каждой новой строке должно быть 0.

Вот как будет выглядеть желаемый результат:

----------------------------
type | latency | urevent |
----------------------------
222  | 4167    | 1       |
222  | 4433    | 2       |
199  | 5109    | 3       |
201  | 5159    | 0       |
251  | 5635    | 4       |
106  | 6618    | 5       |
88   | 6980    | 6       |
88   | 7246    | 7       |
88   | 7512    | 8       |
88   | 7778    | 9       |
61   | 8045    | 10      |
199  | 8311    | 11      |
200  | 8361    | 0       |
251  | 8577    | 12      |
---------------------------



1 Ответ

2 голосов
/ 25 апреля 2020

Мы можем использовать add_row из `tibble

library(tibble)
library(dplyr)
library(tidyr)
df1 %>% 
    add_row(type = acc[1], .after = 3) %>% 
    add_row(type = acc[2], .after = 12) %>% 
    fill(latency) %>%
    mutate(latency = case_when(type %in% acc ~ latency + 50,
               TRUE ~ latency), urevent = replace_na(urevent, 0))
#   type latency urevent
#1   222    4167       1
#2   222    4433       2
#3   199    5109       3
#4   201    5159       0
#5   251    5635       4
#6   106    6618       5
#7    88    6980       6
#8    88    7246       7
#9    88    7512       8
#10   88    7778       9
#11   61    8045      10
#12  199    8311      11
#13  200    8361       0
#14  251    8577      12

Другой вариант - group_split путем создания столбца группировки на основе вхождения значения '199' в типе

library(purrr)
lst1 <- df1 %>%
            group_split(grp = cumsum(type == 199), keep = FALSE)
i1 <-  map_lgl(lst1, ~ .x$type[1] == 199)

lst1[i1] <- map2(lst1[i1], acc, ~
          .x %>%
            add_row(tibble(type = .y, urevent = 0), .after = 1) %>%
            fill(latency) %>% 
            mutate(latency = case_when(type %in% acc ~ latency + 50,
           TRUE ~ latency)))

df2 <- bind_rows(lst1)
df2
# A tibble: 14 x 3
#    type latency urevent
# * <dbl>   <dbl>   <dbl>
# 1   222    4167       1
# 2   222    4433       2
# 3   199    5109       3
# 4   201    5159       0
# 5   251    5635       4
# 6   106    6618       5
# 7    88    6980       6
# 8    88    7246       7
# 9    88    7512       8
#10    88    7778       9
#11    61    8045      10
#12   199    8311      11
#13   200    8361       0
#14   251    8577      12

Или другой вариант - расширить строки на uncount, а затем replace значения в столбцах соответственно на основе дублированных номеров строк

df1 %>%
    mutate(rn = row_number()) %>%
    uncount(1 + (type == 199))  %>%
    mutate(type = replace(type, duplicated(rn), acc), 
           urevent = replace(urevent, duplicated(rn), 0)) %>% 
    group_by(rn) %>%
    mutate(latency = if(n() > 1) replace(latency, 2,  first(latency) + 50) 
               else latency) %>%
    ungroup %>%
    select(-rn)
# A tibble: 14 x 3
#    type latency urevent
#   <dbl>   <dbl>   <dbl>
# 1   222    4167       1
# 2   222    4433       2
# 3   199    5109       3
# 4   201    5159       0
# 5   251    5635       4
# 6   106    6618       5
# 7    88    6980       6
# 8    88    7246       7
# 9    88    7512       8
#10    88    7778       9
#11    61    8045      10
#12   199    8311      11
#13   200    8361       0
#14   251    8577      12
...