Извлечение нескольких фреймов данных из одного с критериями выбора
Пусть это будет мой набор данных:
df <- data.frame(x1 = runif(1000), x2 = runif(1000), x3 = runif(1000),
split = sample( c('SPLITMEHERE', 'OBS'), 1000, replace=TRUE, prob=c(0.04, 0.96) ))
Итак, у меня есть некоторые переменные (в моем случае 15) и критерии, по которым я хочу разделить data.frame на несколько data.frames.
Мои критерии следующие: каждый раз, когда появляется "SPLITMEHERE", я хочу взять все значения или все "OBS" под ним и получить data.frame только из этих наблюдений. Итак, если в начале data.frame 20 'SPLITMEHERE', я хочу в итоге получить 10 data.frames.
Я знаю, что это звучит запутанно и похоже, что в этом нет особого смысла, но это результат извлечения необработанных чисел из ужасно грязного файла.txt для получения значимых данных. По сути, каждый 'SPLITMEHERE' обозначает новую таблицу в этом файле.txt, но каждый округ делится на две таблицы, поэтому я хочу одну таблицу (data.frame) для каждого округа.
В надежде я сделаю это более ясным, вот пример того, что мне нужно. Скажем, первые 20 наблюдений:
x1 x2 x3 split
1 0.307379064 0.400526799 0.2898194543 SPLITMEHERE
2 0.465236674 0.915204924 0.5168274657 OBS
3 0.063814420 0.110380201 0.9564822116 OBS
4 0.401881416 0.581895095 0.9443995396 OBS
5 0.495227871 0.054014926 0.9059893533 SPLITMEHERE
6 0.091463620 0.945452614 0.9677482590 OBS
7 0.876123151 0.702328031 0.9739113525 OBS
8 0.413120761 0.441159673 0.4725571219 OBS
9 0.117764512 0.390644966 0.3511555807 OBS
10 0.576699384 0.416279417 0.8961428872 OBS
11 0.854786077 0.164332814 0.1609375612 OBS
12 0.336853841 0.794020157 0.0647337821 SPLITMEHERE
13 0.122690541 0.700047133 0.9701538396 OBS
14 0.733926139 0.785366852 0.8938749305 OBS
15 0.520766503 0.616765349 0.5136788010 OBS
16 0.628549288 0.027319848 0.4509875809 OBS
17 0.944188977 0.913900539 0.3767973795 OBS
18 0.723421337 0.446724318 0.0925365961 OBS
19 0.758001243 0.530991725 0.3916394396 SPLITMEHERE
20 0.888036748 0.862066601 0.6501050976 OBS
То, что я хотел бы получить это:
data.frame1:
1 0.465236674 0.915204924 0.5168274657 OBS
2 0.063814420 0.110380201 0.9564822116 OBS
3 0.401881416 0.581895095 0.9443995396 OBS
4 0.091463620 0.945452614 0.9677482590 OBS
5 0.876123151 0.702328031 0.9739113525 OBS
6 0.413120761 0.441159673 0.4725571219 OBS
7 0.117764512 0.390644966 0.3511555807 OBS
8 0.576699384 0.416279417 0.8961428872 OBS
9 0.854786077 0.164332814 0.1609375612 OBS
А также
data.frame2:
1 0.122690541 0.700047133 0.9701538396 OBS
2 0.733926139 0.785366852 0.8938749305 OBS
3 0.520766503 0.616765349 0.5136788010 OBS
4 0.628549288 0.027319848 0.4509875809 OBS
5 0.944188977 0.913900539 0.3767973795 OBS
6 0.723421337 0.446724318 0.0925365961 OBS
7 0.888036748 0.862066601 0.6501050976 OBS
Таким образом, разделить столбец показывает только, где разделить, данные в столбцах, где написано "SPLITMEHERE" бессмысленно. Но это не беспокоит, так как я могу удалить эти строки позже, дело в том, чтобы разделить несколько фреймов данных на основе этого критерия.
Очевидно, что только split()
функция и filter()
от dplyr
здесь бы не хватило Реальная проблема заключается в том, что строки, которые должны разделять data.frames (то есть все остальные 'SPLITMEHERE'), появляются не так, как в моем предыдущем примере. Когда-то есть разрыв в 3 строки, а в других случаях это может быть 10 или 15 строк.
Есть ли способ извлечь это эффективно в R?
1 ответ
Самая трудная часть проблемы - это создание групп. Как только у нас будут правильные группировки, достаточно просто использовать split
чтобы получить свой результат.
С учетом сказанного, вы можете использовать cumsum
для групп. Здесь я делю cumsum
на 2 и использовать ceiling
так что любые группы из 2 SPLITMEHERE
Это будет свернуто в один. Я также использую ifelse
чтобы исключить строки с SPLITMEHERE
:
df$group <- ifelse(df$split != "SPLITMEHERE", ceiling(cumsum(df$split=="SPLITMEHERE")/2), 0)
res <- split(df, df$group)
Результатом является список с фреймом данных для каждого group
, Группы с 0
те, которые вы хотите выбросить.