#r #dataframe #filter #group-by #datatables
#r #фрейм данных #Фильтр #группирование по #таблицы данных
Вопрос:
У меня есть большой набор данных csv с более чем 45 тыс. строк и 19 различными переменными. Я хотел бы отфильтровать его по определенной переменной (V4), чтобы каждая отфильтрованная группа начиналась с 0, а затем следующий 0 будет означать начало новой group / dataframe / datatable, сохраняя при этом все остальные переменные внутри этой новой таблицы. Мне нужны эти отдельные группы для дальнейшего анализа каждого случая данных. Я пытался:
filtered_data <- my_data %>%
group_by("V4") %>%
filter("V4" == 0 amp; "V4" !=0)
View(filtered_data)
Кажется, что первый «V4» == 0 работает, но я пытаюсь определить конец каждого отфильтрованного фрейма данных, например, как фильтровать от 0 до 3, затем от 0 до 5 и т.д.
Как я могу определить длину каждого случая? Существует ли логический оператор, который сохраняет каждую группу до того, как V4 снова превратится в 0? Или было бы лучше создать цикл?
Пример my_data:
V1 V2 V3 V4 . . . V19
1 0
2 1
3 2
4 ` 3
5 0
6 1
7 2
8 3
9 4
10 5
11 0
...
45k
Ответ №1:
Вот способ сгруппировать ваши строки с помощью базовой арифметики. Я создаю группы, используя совокупную сумму индикаторной переменной (V4 равно 0 или нет), и разбиваю data.frame на отдельные фреймы данных, используя group_split
.
# example data 12000 rows in total, 4000 groups of 3 rows
df <- data.frame(V1 = 1:12000,
V2 = sample(LETTERS, 12000, replace = T),
V4 = rep(0:2, 4000))
df <- df %>%
mutate(Groups = ifelse(V4 == 0, 1, 0),
Groups = cumsum(Groups)) %>%
group_split(Groups)
Итак, первая группа / фрейм данных
> df[[1]]
# A tibble: 3 x 4
V1 V2 V4 Groups
<int> <chr> <int> <dbl>
1 1 L 0 1
2 2 L 1 1
3 3 Y 2 1
второй
> df[[2]]
# A tibble: 3 x 4
V1 V2 V4 Groups
<int> <chr> <int> <dbl>
1 4 Z 0 2
2 5 N 1 2
3 6 Y 2 2
и так далее.
Если вы хотите сохранить каждый data.frame отдельно, вы могли бы использовать что-то вроде этого:
# new environment that holds all data.frames
dfEnv <- new.env()
df %>%
mutate(Groups = ifelse(V4 == 0, 1, 0),
Groups = cumsum(Groups)) %>%
group_by(Groups) %>%
do({
# save every group inside the new environment as a single data.frame
dfEnv[[paste0("Group_", unique(.$Groups))]] <- .
})
Теперь у вас есть dfEnv$Group_1
, dfEnv$Group_2
, … и так далее.
Внутри do()
вы также можете использовать saveRDS
или write.csv
для сохранения данных на диск.
Комментарии:
1. Спасибо! Я замечаю, что для вычисления требуется много времени, например, более 1600 групп, поскольку каждая из них печатается на экране и не сохраняется отдельно. Есть ли какой-либо способ ускорить этот процесс?
2. Просто сохраните список, тогда ничего не будет напечатано. Я редактирую свой ответ.