Как добавить переменную в `df2`, которая задает количество строк определенного уровня c переменной из` df1`, используя `dplyr` или` data.table` - PullRequest
0 голосов
/ 08 января 2020

У меня есть датафрейм df1, который суммирует обнаружения видов fi sh с течением времени благодаря использованию передатчиков acousti c (прикрепленных к fi sh) и приемников acousti c (помещенных в площадь). Эти передатчики имеют два датчика, один для измерения активности и другой для измерения глубины fi sh. Только передатчики могут отправлять только один вид данных (активность или глубина), и они посылают сигнал каждые несколько минут как минимум. В конце мы получаем кадр данных со временем обнаружения fi sh (DateTime), приемник, который обнаружил человека (Receiver), передатчик, который был обнаружен (Transmitter) а также тип информации, которую отправил передатчик (Sensor). Ниже я показываю воспроизводимый пример:

df1<-data.frame(DateTime=c("2016-08-01 12:04:07","2016-08-01 12:06:07","2016-08-01 13:12:12","2016-08-01 14:04:07","2016-08-01 15:01:45","2016-08-01 15:34:07","2016-08-01 16:25:16","2016-08-01 16:29:16","2016-08-01 16:33:16","2016-08-01 16:54:16","2016-08-01 16:58:16","2016-08-01 17:13:16","2016-08-01 17:21:16","2016-08-01 17:23:42","2016-08-01 17:27:16","2016-08-01 17:28:16","2016-08-01 17:29:28","2016-08-01 17:42:08"),
                Receiver=c( "V6", "V7", "V6", "V6", "V7", "V7", "V6", "V6", "V6", "V7", "V7", "V7", "V6", "V6", "V6", "V9", "V7", "V4" ),
                Transmitter=c(16 , 17, 16, 16, 17, 16, 17, 16, 16, 16, 17, 16, 16, 17, 17, 17, 16, 17),
                Sensor=c("Activity","Depth","Activity","Activity","Depth","Activity","Activity","Depth","Activity","Activity","Activity","Depth","Activity","Activity","Depth","Activity","Activity","Activity"))
df1$DateTime<- as.POSIXct(df1$DateTime, format= "%Y-%m-%d %H:%M:%S", tz= "UTC")

df1

              DateTime Receiver Transmitter   Sensor
1  2016-08-01 12:04:07       V6          16 Activity
2  2016-08-01 12:06:07       V7          17    Depth
3  2016-08-01 13:12:12       V6          16 Activity
4  2016-08-01 14:04:07       V6          16 Activity
5  2016-08-01 15:01:45       V7          17    Depth
.            .                .           .       .
.            .                .           .       .

Я хочу создать фрейм данных df2, в котором эта информация размещена по-другому. Я хочу использовать почасовые интервалы, в которых каждый час охватывает полчаса до и полчаса после (RoundTime). Для каждого RoundTime я хочу для каждого передатчика (Transmitter) количество обнаруженных раз (Num_det), количество разных приемников, которые его обнаружили (Num_Rec), код этих приемников (Which_Rec), количество обнаружений с Activity info (n_Activity) и количество обнаружений с Depth info (n_Depth). Я ожидал бы это:

df2
             RoundTime Transmitter Num_det n_Activity n_Depth Num_Rec Which_Rec
1  2016-08-01 12:00:00          16       1          1       0       1        V6
2  2016-08-01 12:00:00          17       1          0       1       1        V7
3  2016-08-01 13:00:00          16       1          1       0       1        V6
4  2016-08-01 13:00:00          17       0          0       0      NA      <NA>
5  2016-08-01 14:00:00          16       1          1       0       1        V6
6  2016-08-01 14:00:00          17       0          0       0      NA      <NA>
7  2016-08-01 15:00:00          16       0          0       0      NA      <NA>
8  2016-08-01 15:00:00          17       1          0       1       1        V7
9  2016-08-01 16:00:00          16       2          1       1       2     V6 V7
10 2016-08-01 16:00:00          17       1          1       0       1        V6
11 2016-08-01 17:00:00          16       5          4       1       2     V6 V7
12 2016-08-01 17:00:00          17       4          3       1       3  V6 V7 V9
13 2016-08-01 18:00:00          16       0          0       0      NA      <NA>
14 2016-08-01 18:00:00          17       1          1       0       1        V4

До сих пор я получил df2 со всеми переменными, кроме n_Activity и n_Depth. Здесь я показываю код и результат:

library(lubridate)
library(tidyverse)
df2<-df1 %>% 
   # grouped by rounding the date by hour, Transmitter column
   group_by(RoundTime = round_date(DateTime, "hour"), Transmitter) %>% 
   # get the Num_det as number of rows, add more groups
   group_by(Num_det = n(), 
           which_Rec = toString(sort(unique(Receiver))), add = TRUE) %>%        
   # get the number of distinct elements of Receiver
   summarise(Num_Rec = n_distinct(Receiver)) %>% 
   ungroup %>% 
   # expand the data to fill the missing combinations 
   complete(RoundTime, Transmitter, fill = list(Num_det = 0))%>% 
   select(RoundTime, Transmitter, Num_det, Num_Rec, which_Rec)

df2
# A tibble: 14 x 5
   RoundTime               Transmitter Num_det Num_Rec which_Rec 
   <dttm>                        <dbl>   <dbl>   <int> <chr>     
 1 2016-08-01 12:00:00.000          16       1       1 V6        
 2 2016-08-01 12:00:00.000          17       1       1 V7        
 3 2016-08-01 13:00:00.000          16       1       1 V6        
 4 2016-08-01 13:00:00.000          17       0      NA NA        
 5 2016-08-01 14:00:00.000          16       1       1 V6        
 6 2016-08-01 14:00:00.000          17       0      NA NA        
 7 2016-08-01 15:00:00.000          16       0      NA NA        
 8 2016-08-01 15:00:00.000          17       1       1 V7        
 9 2016-08-01 16:00:00.000          16       2       2 V6, V7    
10 2016-08-01 16:00:00.000          17       1       1 V6        
11 2016-08-01 17:00:00.000          16       5       2 V6, V7    
12 2016-08-01 17:00:00.000          17       4       3 V6, V7, V9
13 2016-08-01 18:00:00.000          16       0      NA NA        
14 2016-08-01 18:00:00.000          17       1       1 V4     

Кто-нибудь знает, какой код я должен добавить к предложенному ранее, чтобы создать переменные n_Activity и n_Depth? Если вы знаете, как сделать это с пакетом, data_table еще лучше, поскольку мой реальный информационный фрейм содержит миллионы строк, а data.table более эффективен.

1 Ответ

1 голос
/ 08 января 2020

Полагаю, все, что вам нужно сделать, это подсчитать количество "Activity" и "Depth" на группу в вашем текущем коде, и я не знаю, почему у вас есть два group_by там.

library(dplyr)
library(lubridate)

df1 %>% 
  group_by(RoundTime = round_date(DateTime, "hour"), Transmitter) %>% 
  summarise(Num_det = n(), 
            which_Rec = toString(sort(unique(Receiver))),
            Num_Rec = n_distinct(Receiver), 
            n_Activity = sum(Sensor == "Activity"), 
            n_Depth = sum(Sensor == "Depth")) %>%
   ungroup %>% 
   tidyr::complete(RoundTime, Transmitter, 
           fill = list(Num_det = 0, n_Activity = 0, n_Depth = 0))


# A tibble: 14 x 7
#   RoundTime           Transmitter Num_det which_Rec  Num_Rec n_Activity n_Depth
#   <dttm>                    <dbl>   <dbl> <chr>        <int>      <dbl>   <dbl>
# 1 2016-08-01 12:00:00          16       1 V6               1          1       0
# 2 2016-08-01 12:00:00          17       1 V7               1          0       1
# 3 2016-08-01 13:00:00          16       1 V6               1          1       0
# 4 2016-08-01 13:00:00          17       0 NA              NA          0       0
# 5 2016-08-01 14:00:00          16       1 V6               1          1       0
# 6 2016-08-01 14:00:00          17       0 NA              NA          0       0
# 7 2016-08-01 15:00:00          16       0 NA              NA          0       0
# 8 2016-08-01 15:00:00          17       1 V7               1          0       1
# 9 2016-08-01 16:00:00          16       2 V6, V7           2          1       1
#10 2016-08-01 16:00:00          17       1 V6               1          1       0
#11 2016-08-01 17:00:00          16       5 V6, V7           2          4       1
#12 2016-08-01 17:00:00          17       4 V6, V7, V9       3          3       1
#13 2016-08-01 18:00:00          16       0 NA              NA          0       0
#14 2016-08-01 18:00:00          17       1 V4               1          1       0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...