Агрегировать столбец из набора данных другой длины с несколькими условиями ifelse - PullRequest
0 голосов
/ 29 марта 2019

У меня есть два набора данных: один с путевыми точками и один с треками.

Я хочу добавить переменную mode режима набора треков в набор данных путевых точек в зависимости от времени отслеживания

В наборе данных путевых точек есть переменная "tracked_at"

`

ID <- c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 16, 17, 18, 19, 20)
tracked_at <- ymd_hms(c("2017-10-16 06:00:02", "2017-10-16 06:00:07", "2017-10-16 06:01:15", "2017-10-16 06:02:09",
                     "2017-10-16 06:02:50", "2017-10-16 06:04:05", "2017-10-16 06:04:15", "2017-10-16 06:10:15",
                     "2017-10-16 06:14:15", "2017-10-16 06:16:15", "2017-10-16 06:18:30", "2017-10-16 06:18:45", 
                     "2017-10-16 06:19:15", "2017-10-16 06:19:40", "2017-10-16 06:19:55", "2017-10-17 08:08:02", 
                     "2017-10-17 08:10:02", "2017-10-17 08:16:02", "2017-10-17 08:17:02", "2017-10-18 15:00:00"))

lat <- c(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)
long <- c(2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2)
id_user<- c(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,3)
df1 <- data.frame(ID, tracked_at,lat, long, id_user )

print(df1)
   ID          tracked_at lat long id_user
1   1 2017-10-16 06:00:02   1    2       1
2   2 2017-10-16 06:00:07   1    2       1
3   3 2017-10-16 06:01:15   1    2       1
4   4 2017-10-16 06:02:09   1    2       1
5   5 2017-10-16 06:02:50   1    2       1
6   6 2017-10-16 06:04:05   1    2       1
7   7 2017-10-16 06:04:15   1    2       1
8   8 2017-10-16 06:10:15   1    2       1
9   9 2017-10-16 06:14:15   1    2       1
10 10 2017-10-16 06:16:15   1    2       1
11 11 2017-10-16 06:18:30   1    2       1
12 12 2017-10-16 06:18:45   1    2       1
13 13 2017-10-16 06:19:15   1    2       1
14 14 2017-10-16 06:19:40   1    2       1
15 15 2017-10-16 06:19:55   1    2       1
16 16 2017-10-17 08:08:02   1    2       2
17 17 2017-10-17 08:10:02   1    2       2
18 18 2017-10-17 08:16:02   1    2       2
19 19 2017-10-17 08:17:02   1    2       2
20 20 2017-10-18 15:00:00   1    2       3

В наборе данных треков у меня есть переменные" launch_at "и" finish_a "

started_at <- ymd_hms(c("2017-10-16 06:00:05", "2017-10-16 06:04:15", "2017-10-16 06:18:31", "2017-10-17 08:10:02"))
finished_a <- ymd_hms(c("2017-10-16 06:02:10", "2017-10-16 06:18:30", "2017-10-16 06:19:45", "2017-10-17 08:16:02"))
id_user <- c(1, 1, 1, 2)
Mode <- c("Walk", "Train", "Walk", "Car")
df2 <- data.frame(started_at,finished_a, id_user, Mode )
print(df2)

           started_at          finished_a id_user  Mode
1 2017-10-16 06:00:05 2017-10-16 06:02:10       1  Walk
2 2017-10-16 06:04:15 2017-10-16 06:18:30       1 Train
3 2017-10-16 06:18:31 2017-10-16 06:19:45       1  Walk
4 2017-10-17 08:10:02 2017-10-17 08:16:02       2   Car

3 переменные - формат даты (ymd_hms) и путевые точкитакже отслеживаются, когда люди неподвижны, поэтому столбец режима должен заполняться большую часть времени NA.Я хотел бы добавить, что в случае, если NA перед режимом «Автобус» или «Поезд» и после «Прогулка», то это «Время ожидания».

Это будет идеальный набор данных:

ID <- c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 16, 17, 18, 19, 20)
tracked_at <- ymd_hms(c("2017-10-16 06:00:02", "2017-10-16 06:00:07", "2017-10-16 06:01:15", "2017-10-16 06:02:09",
                 "2017-10-16 06:02:50", "2017-10-16 06:04:05", "2017-10-16 06:04:15", "2017-10-16 06:10:15",
                 "2017-10-16 06:14:15", "2017-10-16 06:16:15", "2017-10-16 06:18:30", "2017-10-16 06:18:45", 
                 "2017-10-16 06:19:15", "2017-10-16 06:19:40", "2017-10-16 06:19:55", "2017-10-17 08:08:02", 
                 "2017-10-17 08:10:02", "2017-10-17 08:16:02", "2017-10-17 08:17:02", "2017-10-18 15:00:00"))

lat <- c(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)
long <- c(2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2)
id_user<- c(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,3)
NeWmode <- c("NA","Walk", "Walk", "Walk", "Waiting Time", "Waiting Time", "Train", "Train", "Train", "Train", "Train",
             "Walk","Walk", "Walk", "NA", "NA", "Car", "Car", "NA", "NA")
df3 <- data.frame(ID, tracked_at,lat, long, id_user, Newmode )
print(df3)

ID              tracked_at lat long id_user      Newmode
1   1 2017-10-16 06:00:02   1    2       1           NA
2   2 2017-10-16 06:00:07   1    2       1         Walk
3   3 2017-10-16 06:01:15   1    2       1         Walk
4   4 2017-10-16 06:02:09   1    2       1         Walk
5   5 2017-10-16 06:02:50   1    2       1 Waiting Time
6   6 2017-10-16 06:04:05   1    2       1 Waiting Time
7   7 2017-10-16 06:04:15   1    2       1        Train
8   8 2017-10-16 06:10:15   1    2       1        Train
9   9 2017-10-16 06:14:15   1    2       1        Train
10 10 2017-10-16 06:16:15   1    2       1        Train
11 11 2017-10-16 06:18:30   1    2       1        Train
12 12 2017-10-16 06:18:45   1    2       1         Walk
13 13 2017-10-16 06:19:15   1    2       1         Walk
14 14 2017-10-16 06:19:40   1    2       1         Walk
15 15 2017-10-16 06:19:55   1    2       1           NA
16 16 2017-10-17 08:08:02   1    2       2           NA
17 17 2017-10-17 08:10:02   1    2       2          Car
18 18 2017-10-17 08:16:02   1    2       2          Car
19 19 2017-10-17 08:17:02   1    2       2           NA
20 20 2017-10-18 15:00:00   1    2       3           NA

Мой лучший выбор был:

   id1 <-filter(df1, id_user==1) #filtering by users
id1Moda <- filter(df2, id_user==1)

id1Moda$mode.num[id1Moda$Mode=="Walk"] <-1
id1Moda$mode.num[id1Moda$Mode=="Train"] <-2
id1Moda$mode.num[id1Moda$Mode=="Car"] <-3

  id1$mode <- NA
for(i in 1:nrow(id1Moda)){
  for(k in 1:nrow(id1)){
    if((id1$tracked_at[k] >= id1Moda$started_at[i]) & (id1$tracked_at[k] <= id1Moda$finished_a[i])){
      id1$Newmode[k] <- id1Moda$mode.num[i]
    } else {
    }
  }
}

В идеале, я не фильтрую по пользователям, потому что у меня есть 50 пользователей для анализа Кроме того, цикл очень очень медленный, так как набор данных болеечем 280 000 баллов за этот идентификатор.Всего в базе данных собрано 38 000 000 точек данных.

Примечания:

  1. Треки не обязательно начинаются при записи путевой точки, поэтому я использую интервал
  2. В этой попытке мне нужно было передать переменнуюот фактора к целому числу Я не смог справиться с такими переменными, как: id1Moda$mode.num[id1Moda$Mode=="Walk"] <-1

Спасибо за помощь!

1 Ответ

1 голос
/ 29 марта 2019

Попробуйте это.

Используйте объединение и фильтры для выполнения вашей задачи. Для больших наборов данных внутреннее объединение может потребовать много памяти

Примечание. Я изменил имя finished_a на finished_at

df1 %>% inner_join(df2, by="id_user") %>% 
  filter(tracked_at >= started_at,  tracked_at <=finished_at)


   ID          tracked_at lat long id_user          started_at         finished_at  Mode
1   2 2017-10-16 06:00:07   1    2       1 2017-10-16 06:00:05 2017-10-16 06:02:10  Walk
2   3 2017-10-16 06:01:15   1    2       1 2017-10-16 06:00:05 2017-10-16 06:02:10  Walk
3   4 2017-10-16 06:02:09   1    2       1 2017-10-16 06:00:05 2017-10-16 06:02:10  Walk
4   7 2017-10-16 06:04:15   1    2       1 2017-10-16 06:04:15 2017-10-16 06:18:30 Train
5   8 2017-10-16 06:10:15   1    2       1 2017-10-16 06:04:15 2017-10-16 06:18:30 Train
6   9 2017-10-16 06:14:15   1    2       1 2017-10-16 06:04:15 2017-10-16 06:18:30 Train
7  10 2017-10-16 06:16:15   1    2       1 2017-10-16 06:04:15 2017-10-16 06:18:30 Train
8  11 2017-10-16 06:18:30   1    2       1 2017-10-16 06:04:15 2017-10-16 06:18:30 Train
9  12 2017-10-16 06:18:45   1    2       1 2017-10-16 06:18:31 2017-10-16 06:19:45  Walk
10 13 2017-10-16 06:19:15   1    2       1 2017-10-16 06:18:31 2017-10-16 06:19:45  Walk
11 14 2017-10-16 06:19:40   1    2       1 2017-10-16 06:18:31 2017-10-16 06:19:45  Walk
12 17 2017-10-17 08:10:02   1    2       2 2017-10-17 08:10:02 2017-10-17 08:16:02   Car
13 18 2017-10-17 08:16:02   1    2       2 2017-10-17 08:10:02 2017-10-17 08:16:02   Car

аналогичный вопрос обсуждается в

Объединение таблиц на основе нескольких диапазонов в R

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...