Создание переменной — определение возраста

#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 это фиктивная переменная, которую вы можете отменить после понимания того, что было сделано