Stata: разделить упорядоченный по времени массив на непересекающиеся множества
Я ищу способ Stata разделить упорядоченный по времени массив на подмножества, которые не содержат перекрывающихся элементов / наблюдений.
Пример: допустим, у меня есть переменная meal
для каждого человека в день, и я хотел бы определить, когда человек потенциально переключается на другую диету: diet_type
быть сгенерированным. Я предполагаю, что, как только человек меняет диету - он никогда не возвращается, поэтому в первом примере следует назначить прием пищи "с", потому что после него следует больше "а" и "б".
id day_id meal diet_type
1 1 a 1
1 2 b 1
1 3 c 1
1 4 a 1
1 5 b 1
1 6 d 2
1 7 e 2
1 8 d 2
В моей настоящей задаче у меня около 100 тысяч человек и около 1000 ежедневных наблюдений каждый.
Я уже реализовал это в Python, и теперь мне интересно, можно ли решить подобные проблемы с помощью Stata.
Обновление: мне все равно, есть ли у людей одинаковые диеты, мне просто нужно определить день перемен для каждого человека.
Вот идея кода, который у меня есть в python:
import pandas as pd
import numpy as np
# create example data
df1 = pd.DataFrame({'id': np.full(10, 0), 'day_id': range(10),
'meal': ['a','b','c','a','b','d','e','e','f','d']},
index=range(10))
df2 = pd.DataFrame({'id': np.full(10, 1), 'day_id': range(10),
'meal': ['k','l','m','m','l','m','m','n','m','m']},
index=range(10,20))
mealsDf = df1.append(df2)
# create a list of individuals to loop over
list = mealsDf.id.unique()
result_df = pd.DataFrame()
for id in list:
# select entries in dataframe for this id
df = mealsDf.loc[mealsDf.id == id]
# starting with the fist day check for disjoint sets of meals
df = df.sort('day_id')
diet_type = []
m = 0
d = 0
for j in range(len(df)):
a = df.meal[m:j+1]
b = df.meal[j+1:len(df)]
if set(a).isdisjoint(b):
diet_type[m:j+1] = np.full(j+1-m, d)
m = j + 1
d = d + 1
df['diet_type'] = diet_type
if len(result_df) == 0:
result_df = df
else:
result_df = result_df.append(df)
print(result_df)
который дает
day_id id meal diet_type
0 0 0 a 0
1 1 0 b 0
2 2 0 c 0
3 3 0 a 0
4 4 0 b 0
5 5 0 d 1
6 6 0 e 1
7 7 0 e 1
8 8 0 f 1
9 9 0 d 1
10 0 1 k 0
11 1 1 l 1
12 2 1 m 1
13 3 1 m 1
14 4 1 l 1
15 5 1 m 1
16 6 1 m 1
17 7 1 n 1
18 8 1 m 1
19 9 1 m 1