У меня есть фрейм данных с двумя столбцами, содержащими даты. Я хотел бы отфильтровать каждую комбинацию идентификатора образца /variable/measurement_date на основе минимальной разницы больше нуля между Measurement_date и date2. Я попытался сгруппировать фрейм данных по идентификатору образца, переменной и Measurement_date, а затем отфильтровать его, заменив все различия дат меньше нуля на NA. Вот мой код:
start_date <- as.Date('2021-01-01')
end_date <- as.Date('2021-12-30')
set.seed(1)
cheese <- data.frame(sample_id = c(1,1,1,1,1,1,1,1,1,1,1,1),
variable = c('a','a','a','a','a','a',
'b','b','b','b','b','b'),
value = runif (n = 12, min = 1, max = 10),
measurement_date = c('2021-06-01','2021-06-01','2021-06-01',
'2021-09-21','2021-09-21','2021-09-21',
'2021-06-01','2021-06-01','2021-06-01',
'2021-09-21','2021-09-21','2021-09-21'),
date2 = as.Date(sample( as.numeric(start_date): as.numeric(end_date), 12,
replace = T),
origin = '1970-01-01'))
library(dplyr)
filtered <- cheese %>% group_by(sample_id, variable, measurement_date)
filtered %>%
filter(difftime(measurement_date,date2) ==
min(replace(difftime(measurement_date, date2))>0,NA),na.rm=TRUE)
Это пример кадра данных:
sample_id variable value measurement_date date2
1 a 3.389578 2021-06-01 2021-03-26
1 a 4.349115 2021-06-01 2021-10-04
1 a 6.155680 2021-06-01 2021-12-28
1 a 9.173870 2021-09-21 2021-11-26
1 a 2.815137 2021-09-21 2021-09-20
1 a 9.085507 2021-09-21 2021-11-25
1 b 9.502077 2021-06-01 2021-03-20
1 b 6.947180 2021-06-01 2021-08-01
1 b 6.662026 2021-06-01 2021-02-06
1 b 1.556076 2021-09-21 2021-04-15
1 b 2.853771 2021-09-21 2021-08-05
1 b 2.589011 2021-09-21 2021-06-14
В этом примере есть четыре комбинации sample_id/переменная/дата измерения:
sample_id, variable, measurement_date
1,a,2021-06-01
1,b,2021-06-01
1,a,2021-09,21
1,b,2021-09-21
Я хотел бы сгруппировать фрейм данных по этим комбинациям, а затем посмотреть на разницу между Measurement_date и date2, найдя минимальную разницу между положительными датами. Таким образом, отфильтрованный фрейм данных должен выглядеть так:
sample_id variable value measurement_date date2
1 a 3.389578 2021-06-01 2021-03-26
1 b 9.502077 2021-06-01 2021-03-20
1 a 2.815137 2021-09-21 2021-09-20
1 b 2.853771 2021-09-21 2021-08-05
но мой код просто возвращает ошибку..
> Error: Problem with `filter()` input `..1`.
i Input `..1` is `==...`.
x argument "values" is missing, with no default
РЕДАКТИРОВАТЬ
Итак, я понял, как получить ожидаемый результат, но мне пришлось создать новый столбец, а затем отфильтровать его на основе этого. Я все еще хотел бы знать, как это сделать, не создавая новый столбец.
cheese$diff <- as.Date(cheese$measurement_date) - cheese$date2
filtered <- cheese %>% group_by(sample_id, variable, measurement_date) %>%
filter(diff == min(diff[diff>0]))
извините, @jdobres, я понимаю, что мой вопрос был не слишком ясен, и у меня возникла проблема с установкой семени. Я включил исходный фрейм данных в свое редактирование. По сути, я хотел бы сгруппировать фрейм данных по каждой комбинации sample_id, переменной и даты измерения, что в этом примере приведет к трем строкам для каждой группировки, а затем вычислить разницу между Measurement_date и date2, возвращая строку, в которой минимальное положительное значение происходит.
Мы можем заменить значения, которые меньше или равны 0, на NA
, а затем использовать which.min
внутри slice
, чтобы нам не нужно было создавать новый столбец.
library(tidyverse)
cheese %>%
mutate(measurement_date = as.Date(measurement_date)) %>%
group_by(sample_id, variable, measurement_date) %>%
slice(which.min((measurement_date - date2)*NA^((measurement_date - date2) <=0)))
Выход
sample_id variable value measurement_date date2
<dbl> <chr> <dbl> <date> <date>
1 1 a 3.39 2021-06-01 2021-03-26
2 1 b 9.50 2021-06-01 2021-03-20
3 1 b 2.85 2021-08-22 2021-08-05
Вы также можете напрямую использовать replace
вместо более короткой записи.
cheese %>%
mutate(measurement_date = as.Date(measurement_date)) %>%
group_by(sample_id, variable, measurement_date) %>%
slice(which.min(replace((measurement_date - date2), (measurement_date - date2)<=0, NA)))
Данные
cheese <- structure(list(sample_id = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1), variable = c("a", "a", "a", "a", "a", "a", "b", "b", "b",
"b", "b", "b"), value = c(3.3895779682789, 4.34911509673111,
6.15568027016707, 9.17387010995299, 2.8151373793371, 9.08550716470927,
9.50207741744816, 6.94718013238162, 6.66202639508992, 1.55607643420808,
2.85377117409371, 2.58901077276096), measurement_date = c("2021-06-01",
"2021-06-01", "2021-06-01", "2021-08-22", "2021-08-22", "2021-08-22",
"2021-06-01", "2021-06-01", "2021-06-01", "2021-08-22", "2021-08-22",
"2021-08-22"), date2 = structure(c(18712, 18904, 18989, 18957,
18890, 18956, 18706, 18840, 18664, 18732, 18844, 18792), class = "Date")), class = "data.frame", row.names = c(NA,
-12L))
Мне непонятно, как ваш ожидаемый результат будет получать значения для «date2» на основе значений в
cheese
. Вы можете уточнить?