Поиск нескольких строк в кадре данных, снизу вверх, если условно?
У меня есть датафрейм с несколькими столбцами, давайте назовем его dat1, и мне нужно извлечь строки в определенных столбцах на основе множества условий. Существует около 350 строк для каждого субъекта, и мне нужно найти последнюю строку определенной строки в определенном столбце, для каждого субъекта, содержащую определенное имя, например, "зеленый", и взять значение из другой строки в той же строке.
subject type value
111 yellow 354
111 green 584
111 yellow 584
111 blue 492
111 green 493
222 blue 459
222 green 583
222 yellow 539
222 blue 392
222 yellow 394
Скажем, мне нужно последнее значение "зеленый" для каждого предмета, как я могу это сделать?
После этого мне также нужно получить значение, которое выше последнего "зеленого", желательно сохранить его в двух отдельных векторах.
last_green before_last_green
493 492
583 459
Я попытался сделать несколько операторов if, в то же время группируя по темам, но даже не добился почти успеха. Я также не смог найти никаких примеров этого раньше.
Можно ли искать первый "зеленый" снизу каждого предмета? Или как еще это можно сделать?
4 ответа
Отвечая на оба вопроса:
df=data.frame("subject"=c(rep(111,5),rep(222,5)),
"type"=c("yellow","green","yellow","blue","green",
"blue","green","yellow","blue","yellow"),
value=c(354,584,584,492,493,459,583,539,392,394),
stringsAsFactors = FALSE)
subject type value
1 111 yellow 354
2 111 green 584
3 111 yellow 584
4 111 blue 492
5 111 green 493
6 222 blue 459
7 222 green 583
8 222 yellow 539
9 222 blue 392
10 222 yellow 394
Создать фильтр df:
filter_=df%>%rownames_to_column()%>%group_by(subject)%>%
filter(type=="green")%>%slice(n())
last_green=filter_$value
before_last_green=df$value[as.numeric(filter_$rowname)-1]
Результаты:
> last_green
[1] 493 583
> before_last_green
[1] 492 459
Объяснение:
Сначала мы создаем имена строк, чтобы отслеживать положение последних green
внешний вид для каждого subject
, Затем мы группируем по subject
и фильтровать по type
мы берем последний элемент на группу с slice()
, Затем мы возвращаем value
в last_green
и value
строки с положением этих предыдущих образцов - 1 (предыдущий).
@thothal @boski @utubun Итак, я опробовал все ваши решения, которые отлично работают на примере данных, которые я привел здесь. Тем не менее, при адаптации его к моим фактическим данным я получаю ошибку
Error in filter_impl(.data, quo) :
Ошибка оценки: объект "тип" не найден.
Из этого я получаю, что тип столбцов, которые я использую, имеет неправильный тип. Я определил их столбцы как символы, которые не помогли. У меня такое чувство, что есть кое-что, чего мне не хватает, чтобы заставить его работать, какая-нибудь подсказка, что?
Код
tidyverse
твой друг:
library(tidyverse)
d <- structure(list(subject = c(111L, 111L, 111L, 111L, 111L,
222L, 222L, 222L, 222L, 222L),
type = c("yellow", "green", "yellow", "blue", "green",
"blue", "green", "yellow", "blue", "yellow"),
value = c(354L, 584L, 584L, 492L, 493L,
459L, 583L, 539L, 392L, 394L)),
row.names = c(NA, -10L),
class = c("tbl_df", "tbl", "data.frame"))
d %>%
group_by(subject) %>%
filter(type == "green") %>%
summarise_all(last)
# A tibble: 2 x 3
# subject type value
# <int> <chr> <int>
# 1 111 green 493
# 2 222 green 583
объяснение
- с
group_by
Вы будете делать следующее за уникальное значениеsubject
- с
filter
вы смотрите только на строки сtype
равноgreen
- с
summarise
вы наконец выбираете только последнюю запись
Вы можете сделать это следующим образом:
library(tidyverse)
dat %>%
rownames_to_column() %>%
group_by(subject) %>%
filter(type == 'green') %>%
summarise(
last_green = last(value),
before_last_green = dat$value[as.numeric(last(rowname)) - 1]
)
Что здесь происходит:
- вы перемещаете имена строк вашего
data.frame
в переменнуюrowname
(см. последнее почему); - вы группируете свои данные по
subject
, чтобы применить следующие операции над подмножествами ваших данных, связанных с конкретнымsubject
; - вы
filter
ваши данные, оставляя толькоgreens
; - и наконец:
- вы
summarize
ваши данные, принимая последниеvalue
для каждого ранее отфильтрованного подмножества и присвоения егоvalue_green
; - Вы заимствуете целое, не преобразованное
dat
из среды, подмножествоvalue
отdat
по строкам, соответствующимlast(ronwame) - 1
вашей.
данные, т.е. данные, которые пришли вsummarize
через трубы.
- вы
Который оценивает:
# A tibble: 2 x 3
subject last_green before_last_green
<int> <int> <int>
1 111 493 492
2 222 583 459
Ваши данные:
dat <- read.table(
text = "subject type value
111 yellow 354
111 green 584
111 yellow 584
111 blue 492
111 green 493
222 blue 459
222 green 583
222 yellow 539
222 blue 392
222 yellow 394",
header = T, stringsAsFactors = F
)