#r #tidyverse
#r #tidyverse
Вопрос:
Для начала, извините, если этот вопрос задавался раньше (я уверен, что задавался, я просто не могу найти правильный ответ)
Допустим, у меня есть следующий фрейм данных. В этом случае бегун Тим получил травму на втором круге. Что я хочу сделать, так это удалить круг № 2 у всех бегунов, поскольку его данные больше нельзя сравнивать.
race <- data.frame("Runner" = c("John","John","Elsa","Elsa","Tim","Tim"),
"Time" = c(1,2,3,4,5,NA),
"Lap" = c(1,2,1,2,1,2)
)
> race
Runner Time Lap
1 John 1 1
2 John 2 2
3 Elsa 3 1
4 Elsa 4 2
5 Tim 5 1
6 Tim NA 2
Итак, в основном, я хочу закончить с фреймом данных с 3 строками. По одной для Джона, Эльзы и Тима, в каждой строке указано время из круга № 1.
Мне нравится работать с tidyverse, поэтому, если есть ответ, который использует dplyr или что-нибудь подобное, я был бы очень признателен.
Комментарии:
1. попробуйте
race[race$Lap == 1, ]
2. Спасибо за ваши ответы. Извините, что не добавил в исходном сообщении, что я хочу, чтобы код работал и с другими наборами данных. Я знаю, что я мог бы использовать filter с Lap == 1 или подмножество с базой R, но это не будет работать с большими наборами данных с гораздо большим количеством бегунов, кругов и т.д.
Ответ №1:
Попробуйте это:
race <- race%>%
filter(Lap == 1)
Комментарии:
1. @DarrenTsai полностью верно, нет необходимости, сила привычки, я думаю. сейчас редактирую.
2. Кстати, добавлено в качестве ответа, потому что я пока не могу оставлять комментарии 🙂
3. Спасибо за ваш ответ. Да, я знаю, что в этом случае я могу просто выполнить фильтрацию, выбрав круг 1, но было бы неплохо получить код, который также работал бы с большими наборами данных, где становится очень сложно просто вручную выбрать определенное значение.
Ответ №2:
Более безопасным подходом было бы сначала найти, Lap
когда кто-либо получил травму ( NA
в Time
), а затем удалить все данные с этого Lap
момента и далее
subset(race[order(race$Lap), ], Lap < Lap[which.max(is.na(Time))])
# Runner Time Lap
#1 John 1 1
#2 Elsa 3 1
#3 Tim 5 1
и с dplyr
это было бы
library(dplyr)
race %>%
arrange(Lap) %>%
filter(Lap < Lap[which.max(is.na(Time))])
Сначала данные упорядочиваются по Lap
, which.max(is.na(Time)
определяется индекс, по которому они были обнаружены впервые NA
, мы берем соответствующий Lap
и сохраняем все строки меньшего размера, чем это Lap
.
Это все равно сработало бы, если у вас в наборе данных 10 Lap
секунд, а какой-то игрок получил травму в 6-й Lap
.
Комментарии:
1. На самом деле это отличный ответ. Я только что попробовал это с большим набором данных, но да, это имеет полный смысл. Теперь я чувствую себя глупо из-за того, что не думал так, как ты. Я пробовал группировать по Runner и другим вещам, которые ни к чему меня не привели, но ваш подход был намного лучше.
Ответ №3:
Вот способ сделать это через базу R. Мы разделяем на Runner
после очистки из NAs. Затем мы intersect
вычеркиваем Lap
и сохраняем только те, которые найдены в этом пересечении, т.Е.
race[race$Lap %in% Reduce(intersect, split(race$Lap[!is.na(race$Time)], race$Runner[!is.na(race$Time)])),]
# Runner Time Lap
#1 John 1 1
#3 Elsa 3 1
#5 Tim 5 1
Комментарии:
1. Интересно. Я пытался использовать функцию intersect, но у меня не получилось заставить ее работать (ну, по крайней мере, не так, как я хотел, чтобы она работала). Хотя это имеет смысл. Я думаю, единственная проблема заключается в том, что было бы сложнее использовать это в конвейере.
Ответ №4:
Мы также можем использовать subset
из base R
subset(race, Lap == 1)