Вычисление последовательностей на основе суммарного количества - PullRequest
5 голосов
/ 23 апреля 2019

Я пытаюсь построить последовательность строк / значений из следующих данных:

# A tibble: 4 x 2
  year_row breaks
  <chr>     <int>
1 2015          7
2 2016          6
3 2017          5
4 2018          5

То есть;

7 + 6 = 13

+ 5 = 18

+ 5 = 23

Ожидаемый результат:

2015     1:7
2016     8:13
2017     14:18
2018     19:23

Где я могу потом использовать последовательности в некоторых функциях / циклах

Данные:

structure(list(year_row = c("2015", "2016", "2017", "2018"), 
    breaks = c(7L, 6L, 5L, 5L)), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -4L))

Ответы [ 3 ]

6 голосов
/ 23 апреля 2019

Идея через базу R,

v1 <- cumsum(df$breaks)
v2 <- c(1, v1+1)
paste(v2[-length(v2)], v1, sep = ':')
#[1] "1:7"   "8:13"  "14:18" "19:23"

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

Если предположить, что мы уже создали v1 и v2, как показано выше, то

Map(`:`, v2[-length(v2)], v1)
#[[1]]
#[1] 1 2 3 4 5 6 7

#[[2]]
#[1]  8  9 10 11 12 13

#[[3]]
#[1] 14 15 16 17 18

#[[4]]
#[1] 19 20 21 22 23

Прикрепив его к вашему фрейму данных,

df$ranges <- Map(`:`, v2[-length(v2)], v1)
df
# A tibble: 4 x 3
#  year_row breaks ranges   
#  <chr>     <int> <list>   
#1 2015          7 <int [7]>
#2 2016          6 <int [6]>
#3 2017          5 <int [5]>
#4 2018          5 <int [5]>
6 голосов
/ 23 апреля 2019

Мы берем совокупную сумму 'перерывов' и lag 'перерывов', а затем делаем paste

library(dplyr)
library(stringr)
df1 %>% 
   mutate(new = cumsum(breaks), 
          new2 =cumsum( lag(breaks, default = 0)) + 1) %>%
   transmute(year_row, new3 = str_c(new2, new, sep=":"))
# A tibble: 4 x 2
#  year_row new3 
#  <chr>    <chr>
#1 2015     1:7  
#2 2016     8:13 
#3 2017     14:18
#4 2018     19:23
3 голосов
/ 23 апреля 2019

Использование той же базовой идеи, что и @akrun, но без lag():

df %>%
 mutate(res = cumsum(breaks),
        res = paste((res - breaks) + 1, res, sep = ":"))

  year_row breaks   res
1     2015      7   1:7
2     2016      6  8:13
3     2017      5 14:18
4     2018      5 19:23

И то же самое только с base R:

res <- cumsum(df$breaks)
df$res <- paste((res - df$breaks) + 1, res, sep = ":")

Или если вы хотите, чтобыфактические векторы:

df %>%
 mutate(res1 = cumsum(breaks),
        res2 = (res1 - breaks) + 1) %>%
 rowwise() %>%
 mutate(res = list(res2:res1)) %>%
 select(-res1, -res2)

  year_row breaks res      
     <int>  <int> <list>   
1     2015      7 <int [7]>
2     2016      6 <int [6]>
3     2017      5 <int [5]>
4     2018      5 <int [5]>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...