#r #variables #inference #feature-engineering #data-wrangling
#r #переменные #вывод #разработка функций #перебор данных
Вопрос:
У меня есть сгруппированный фрейм данных;
Truck <- c('A','A','A','A','B','B','B','B','C','C','C','C')
OilChanged <- c('True','NewOil','False','False','False','False','False','False','True','NewOil','True','NewOil')
Odometer <- c(1000, 1000, 2000,3000,700,800,900,1000,20000,20000,30000,30000)
DF <- data.frame(Truck, OilChanged, Odometer)
# Truck OilChanged Odometer
# 1 A True 1000
# 2 A NewOil 1000
# 3 A False 2000
# 4 A False 3000
# 5 B False 700
# 6 B False 800
# 7 B False 900
# 8 B False 1000
# 9 C True 20000
# 10 C NewOil 20000
# 11 C True 30000
# 12 C NewOil 30000
Я пытаюсь определить возраст масла (в километрах), когда это возможно. Вывод возможен только после замены масла. Если замена масла не происходит, возраст масла останется загадкой (пример: грузовик B).
Ниже приведен желаемый результат;
Truck <- c('A','A','A','A','B','B','B','B','C','C','C','C')
OilChanged <- c('True','NewOil','False','False','False','False','False','False','True','NewOil','True','NewOil')
Odometer <- c(1000, 1000, 2000, 3000,700,800,900,1000,20000,20000,30000,30000)
OilAge <- c(NA,0,1000,2000,NA,NA,NA,NA,NA,0,10000,0)
Result <- data.frame(Truck, OilChanged, Odometer, OilAge)
# Truck OilChanged Odometer OilAge
# 1 A True 1000 NA
# 2 A NewOil 1000 0
# 3 A False 2000 1000
# 4 A False 3000 2000
# 5 B False 700 NA
# 6 B False 800 NA
# 7 B False 900 NA
# 8 B False 1000 NA
# 9 C True 20000 NA
# 10 C NewOil 20000 0
# 11 C True 30000 10000
# 12 C NewOil 30000 0
Примечание: показания одометра между строкой с истинной заменой масла и следующей строкой NewOil всегда будут одинаковыми. Потому что образец масла берется непосредственно перед заменой масла. Но обе строки должны поддерживаться для правильной работы последующих вычислений, таких как формулы скорости изменения.
NA в столбце OilAge означает, что возраст является загадкой.
Комментарии:
1. Гарантируется ли увеличение порядка в столбце одометра для каждого транспортного средства?
2. Да, фрейм данных предварительно отсортирован.
Ответ №1:
Пожалуйста, дайте мне знать, работает ли это решение для вас.
Truck <- c('A','A','A','A','B','B','B','B','C','C','C','C')
OilChanged <- c('True','NewOil','False','False','False','False','False','False','True','NewOil','True','NewOil')
Odometer <- c(1000, 1000, 2000,3000,700,800,900,1000,20000,20000,30000,30000)
DF <- data.frame(Truck, OilChanged, Odometer)
DF %>%
group_by(Truck) %>%
mutate(status = length(unique(OilChanged)),
OilAge = ifelse(OilChanged == "NewOil", 0,
ifelse(OilChanged == "False", Odometer - (Odometer - lag(Odometer)),
ifelse(OilChanged == "True", Odometer - lag(Odometer), NA)))) %>%
mutate(OilAge = ifelse(status !=1, OilAge, NA)) %>%
subset(select = c(Truck, OilChanged, Odometer, OilAge))
Комментарии:
1. Работает отлично.
Ответ №2:
Альтернативный подход
DF %>% group_by(Truck) %>%
mutate(d = cumsum(OilChanged == 'NewOil')) %>%
group_by(Truck, d) %>%
mutate(OilAge = cumsum(c(0*NA^(as.logical(!(first(d)))), diff(NA^(as.logical(!d))*Odometer))))
# A tibble: 12 x 5
# Groups: Truck, d [6]
Truck OilChanged Odometer d OilAge
<chr> <chr> <dbl> <int> <dbl>
1 A True 1000 0 NA
2 A NewOil 1000 1 0
3 A False 2000 1 1000
4 A False 3000 1 2000
5 B False 700 0 NA
6 B False 800 0 NA
7 B False 900 0 NA
8 B False 1000 0 NA
9 C True 20000 0 NA
10 C NewOil 20000 1 0
11 C True 30000 1 10000
12 C NewOil 30000 2 0
d
это фиктивная переменная, которую вы можете отменить после понимания того, что было сделано