Я работаю с набором данных о поездках, который предоставляет информацию для отдельных сегментов поездки каждого человека, включая расстояние и назначение сегмента (например, чтобы идти на работу, ходить по магазинам, возвращаться домой).Это организовано в датафрейме.Я хочу сгруппировать эти сегменты в то, что я называю «цепочечными» или «зацикленными» поездками, увеличивая число цепей / петель каждый раз, когда в предыдущем сегменте происходит возврат домой.
В r я попытался создать цикл for с содержащимся в нем ifelse, который ссылается на значения переменных из предыдущей итерации, а затем заполняет новый столбец, который я уже создал, с нулевыми значениями.(Я знаю, это звучит немного глупо).По сути, я пытался выработать что-то похожее на то, что я смог сделать в Excel, где я создал серию вложенных if.(= IF (DF2 = DF1, IF (DG1 = 11, DI1 + 1, DI1), 1). Это формула из третьей строки, которая относится к значениям в непосредственно предшествующей строке.
Этоэто вывод кода dput для данных:
structure(list(h_id = c(1000002L, 1000002L, 1000002L, 1000002L,
1000013L, 1000013L, 1000013L, 1000013L, 1000013L, 1000013L, 1000013L, 1000013L), p_ID = c(10000022L, 10000022L, 10000022L,
10000022L, 10000131L, 10000131L, 10000132L,10000132L, 10000132L,10000132L,10000132L,10000132L), t_pur = c(6L, 11L, 7L, 11L,
5L, 11L, 1L, 2L, 2L, 11L, 6L, 11L), t_distance = c(753.154936, 753.154936, 4681.630497,
4681.630497, 616.0517311, 616.0517311, 9626,7984, 641.3675, 15076.6182, 21407.5585, 24273.3116, 24273.3116), X = c(1L, 1L, 2L, 2L,
1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L), Conc = c("10000022-1", "10000022-1", "10000022-2", "10000022-2",
"10000131-1", "10000131-1", "10000132-1", "10000132-1", "10000132-1", "10000132-1", "10000132-2", "10000132-2" ), t_mode1 = c(1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L,
1L), has_work = c(0, 0, 0, 0, 0, 0,1, 0, 0, 0, 0, 0), newcol = c(1, 1, 1, 1, 1,
1, 1, 1, 1, 1,1, 1)), .Names = c("h_id", "p_ID", "t_pur", "t_distance", "X", "Conc",
"t_mode1", "has_work", "newcol"), row.names = 3:14, class = "data.frame")
for (i in 1:nrow(loops4)) {
ifelse(i == 1, loops4$newcol[i] <- 1,
ifelse(loops4$p_ID[i-1]==loops4$p_ID,
ifelse(loops4$t_pur[i-1]==11,
loops4$newcol[i] <- loops4$newcol[i-1]+1,
loops4$newcol[i-1]), loops4$newcol[i] <- 1))
}
Здесь, loopps - это мой фрейм данных. newcol - это тот, который я создал для хранения идентификатора цикла. p_ID - уникальный идентификатор, связанный с каждым человеком,t_pur является целью сегмента поездки, а «11» является значением, которое соответствует цели «возвращения домой» (я хочу начинать новый идентификатор цикла каждый раз, когда предыдущий сегмент возвращался домой). После этого я могуобъединить уникальный идентификатор лица и идентификатор цикла для создания уникального идентификатора для каждого цикла.Первый ifelse только для первой записи, чтобы назначить 1 идентификатору цикла, так как не было бы никакого предшествующего значения для цикла, чтобы обратиться к
Я ожидал, что цикл будет проходить через каждую строку в кадре данных, сначала проверяя, ссылается ли запись на того же человека, что и в предыдущей записи.следует проверить, была ли цель поездки из предыдущего ряда «11» или нет.Если это так, он должен добавить 1 к предыдущему идентификатору, чтобы обозначить новый цикл.Если ему не предшествует цель отключения "11", ему следует назначить тот же идентификатор цикла, что и в предыдущей строке, и перейти к следующей строке.Когда он запускается, во-первых, кажется, что он занимает огромное количество времени, а во-вторых, он заполняет все на 1, а не увеличивает и перезапускает, как я ожидал.
Я ожидал такой кадр данных.X - это правильно рассчитанное значение из Excel.newcol - это столбец, в котором я пытался вычислить значение r в newcol.Значения newcol должны совпадать с X, но это не так.(Я обновил таблицу ниже, чтобы отразить в newcol то, что я надеялся увидеть в выходных данных).
h_id p_ID t_pur t_distance X Conc t_mode1 has_work newcol
1000002 10000022 6 753.2 1 10000022-1 1 0 1
1000002 10000022 11 753.2 1 10000022-1 1 0 1
1000002 10000022 7 4681.6 2 10000022-2 1 0 2
1000002 10000022 11 4681.6 2 10000022-2 1 0 2
1000013 10000131 5 616.1 1 10000131-1 1 0 1
1000013 10000131 11 616.1 1 10000131-1 1 0 1
1000013 10000132 1 9626.8 1 10000132-1 1 1 1
1000013 10000132 2 641.4 1 10000132-1 1 0 1
1000013 10000132 2 15076.6 1 10000132-1 1 0 1
1000013 10000132 11 21407.6 1 10000132-1 1 0 1
1000013 10000132 6 24273.3 2 10000132-2 1 0 2
1000013 10000132 11 24273.3 2 10000132-2 1 0 2
ОБНОВЛЕНИЕ:
Я вернулся и немного подумал о назначении внутри конструкции ifelse, основываясь на комментарии ниже, и понял, что это не имеет особого смысла.Поэтому я попытался переписать код следующим образом:
for (i in 1:nrow(loops4)) {
loops4$newcol[i] <- ifelse(i == 1, 1, ifelse (loops4$p_ID[i-1]==loops4$p_ID[i], ifelse(loops4$t_pur[i-1]==11, loops4$newcol[i-1]+1, loops$newcol[i-1], 1)))
}
Но я получил те же неожиданные результаты.
ОБНОВЛЕННОЕ ОБНОВЛЕНИЕ:
Возможно, в моих данных dput ранее произошла ошибка.Я вручную добавил несколько значений.Я вставил новые данные dput ниже.
structure(list(h_id = c(1000002L, 1000002L, 1000002L, 1000002L,
1000013L, 1000013L, 1000013L, 1000013L, 1000013L, 1000013L, 1000013L,
1000013L), p_ID = c(10000022L, 10000022L, 10000022L, 10000022L,
10000131L, 10000131L, 10000132L, 10000132L, 10000132L, 10000132L,
10000132L, 10000132L), t_pur = c(6L, 11L, 7L, 11L, 5L, 11L, 1L,
2L, 2L, 11L, 6L, 11L), t_distance = c(753.154936, 753.154936,
4681.630497, 4681.630497, 616.0517311, 616.0517311, 9626.798385,
641.3674532, 15076.61817, 21407.55851, 24273.31161, 24273.31161
), X = c(1L, 1L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L), Conc = c("10000022-1",
"10000022-1", "10000022-2", "10000022-2", "10000131-1", "10000131-1",
"10000132-1", "10000132-1", "10000132-1", "10000132-1", "10000132-2",
"10000132-2"), t_mode1 = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L), has_work = c(0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0),
newcol = c(1L, 1L, 2L, 2L, 1L, 1L, 0L, 0L, 1L, 1L, 2L, 2L
)), .Names = c("h_id", "p_ID", "t_pur", "t_distance", "X",
"Conc", "t_mode1", "has_work", "newcol"), class = c("tbl_df",
"tbl", "data.frame"), row.names = c(NA, -12L))
И я попробовал подход dplyr, предложенный ниже.
loops_good <- loops5 %>%
group_by(h_id) %>% group_by (p_ID) %>%
mutate(newcol = cumsum(lead(t_pur, default = 0) == 11)) %>%
ungroup()
Полученные результаты - почти то, на что я надеялся.Но не совсем.Все строки с 7 по 10 должны быть сгруппированы вместе с одним и тем же идентификатором в newcol, потому что нет промежуточной "11".Последовательность t_pur равна 1, 2, 2, 11. Но в приведенном ниже выводе значения newcol представлены как 0, 0, 1, 1.
По сути, я пытаюсь связать отдельные сегменты вобщие поездки, начинающиеся каждый раз, когда есть возвращение домой, обозначенное как t_pur == "11".Иногда это просто назад-назад (два сегмента).Но иногда, как в строках 7-10, это 4 сегмента.
Фактический вывод:
h_id p_ID t_pur t_distance X Conc t_mode1 has_work newcol
<int> <int> <int> <dbl> <int> <chr> <int> <dbl> <int>
1 1000002 10000022 6 753. 1 10000022-1 1 0 1
2 1000002 10000022 11 753. 1 10000022-1 1 0 1
3 1000002 10000022 7 4682. 2 10000022-2 1 0 2
4 1000002 10000022 11 4682. 2 10000022-2 1 0 2
5 1000013 10000131 5 616. 1 10000131-1 1 0 1
6 1000013 10000131 11 616. 1 10000131-1 1 0 1
7 1000013 10000132 1 9627. 1 10000132-1 1 1 0
8 1000013 10000132 2 641. 1 10000132-1 1 0 0
9 1000013 10000132 2 15077. 1 10000132-1 1 0 1
10 1000013 10000132 11 21408. 1 10000132-1 1 0 1
11 1000013 10000132 6 24273. 2 10000132-2 1 0 2
12 1000013 10000132 11 24273. 2 10000132-2 1 0 2
Надеялись на вывод:
h_id p_ID t_pur t_distance X Conc t_mode1 has_work newcol
<int> <int> <int> <dbl> <int> <chr> <int> <dbl> <int>
1 1000002 10000022 6 753. 1 10000022-1 1 0 1
2 1000002 10000022 11 753. 1 10000022-1 1 0 1
3 1000002 10000022 7 4682. 2 10000022-2 1 0 2
4 1000002 10000022 11 4682. 2 10000022-2 1 0 2
5 1000013 10000131 5 616. 1 10000131-1 1 0 1
6 1000013 10000131 11 616. 1 10000131-1 1 0 1
7 1000013 10000132 1 9627. 1 10000132-1 1 1 1
8 1000013 10000132 2 641. 1 10000132-1 1 0 1
9 1000013 10000132 2 15077. 1 10000132-1 1 0 1
10 1000013 10000132 11 21408. 1 10000132-1 1 0 1
11 1000013 10000132 6 24273. 2 10000132-2 1 0 2
12 1000013 10000132 11 24273. 2 10000132-2 1 0 2