Разбирать данные в R для добавления переменных (столбцов) и наблюдений (строк) по группам

#r #dplyr

#r #dplyr

Вопрос:

Я пытаюсь изменить порядок набора данных с несколькими тысячами наблюдений (чтобы в конечном итоге использовать функцию drm в пакете DRC), и я устал делать это в Excel. Внутри фрейма данных я хочу добавить время «начала» и «окончания» (с точностью до inf) на основе интервалов, найденных в векторе внутри df. Это означает, что в конечном итоге мне пришлось бы добавить наблюдение (строку), где время последнего «окончания» равно inf. Для этой последней строки (той, что с inf) мне также нужно вычесть общее значение «value» из произвольного числа (в моем примере ниже это будет 50). Все это сгруппировано по двум переменным («Name» и «Rep» в моем примере). Я надеюсь, что есть решение с использованием group_by , но, честно говоря, я буду вне себя от радости при любом решении!

У меня есть набор данных, который выглядит следующим образом;

 # data
names<-c(rep("Luke",30), rep("Han", 30), rep("Leia", 30), rep("OB1", 30))
reps<-c(rep("A", 10), rep("B", 10), rep("C", 10))
time<-rep(seq(1:10), 4)
value<-rep(sample(0:5,10,replace=T), 4)
df<-data.frame(names, reps, time, value)
  

но нужно, чтобы это выглядело так;
Пример структуры данных, которая мне нужна.

введите описание изображения здесь

Я в растерянности. Пожалуйста, помогите!

Ответ №1:

Если я вас правильно понял, мы можем сделать

 library(dplyr)

df1 <- df %>%
          group_by(names, reps) %>%
          mutate(start = lag(time, default = 0), 
                 end = time) 

bind_rows(df1, df1 %>%
                 group_by(names, reps) %>%
                 summarise(start = last(time), 
                            end = Inf, 
                            value = sum(value))) %>%
                 select(-time) %>%
                 arrange(names, reps) 


#  names reps  value start   end
#   <fct> <fct> <int> <dbl> <dbl>
# 1 Han   A         2     0     1
# 2 Han   A         2     1     2
# 3 Han   A         1     2     3
# 4 Han   A         1     3     4
# 5 Han   A         3     4     5
# 6 Han   A         2     5     6
# 7 Han   A         0     6     7
# 8 Han   A         2     7     8
# 9 Han   A         2     8     9
#10 Han   A         5     9    10
#11 Han   A        20    10   Inf
#.....
  

Комментарии:

1. Спасибо Ронак Шоу! Я получаю следующую ошибку; Error in select(., -time) : unused argument (-time) Есть идеи относительно того, почему?

2. @Dustin скорее всего, это связано с конфликтом в использовании select . Попробуйте перезапустить R или явно использовать dplyr::select(-time) вместо select(-time)

3. да, это была проблема, спасибо. Это отлично работает и с моим реальным набором данных! Единственное изменение, которое я внес, — это добавление «50-» перед «value = sum (значение), чтобы строка читалась, 50 - value = sum(value) . Большое вам спасибо!

Ответ №2:

Мы можем сделать это, data.table shift указав ‘time’, добавив ‘Inf’ в конце ‘time’, чтобы создать end разницу в 50 от sum ‘value’ для ‘value’ после группировки по ‘именам’ и ‘представлениям’

 library(data.table)
setDT(df)[,  {stL <-  last(time)
              enL <- Inf
             vL <- 50- sum(value)
        .(start = c(shift(time, fill = 0), stL), 
          end = c(time, enL), 
          value = c(value, vL))}, .(names, reps)]
#     names reps start end value
#  1:  Luke    A     0   1     0
#  2:  Luke    A     1   2     3
#  3:  Luke    A     2   3     3
#  4:  Luke    A     3   4     4
#  5:  Luke    A     4   5     0
# ---                           
#128:   OB1    C     6   7     3
#129:   OB1    C     7   8     0
#130:   OB1    C     8   9     2
#131:   OB1    C     9  10     5
#132:   OB1    C    10 Inf    27