Использование case_when для подстановки данных - PullRequest
0 голосов
/ 17 октября 2019

Я все еще новичок в R, и у меня возникла проблема. У меня есть файл с необработанными данными:

dfRawData <-
  data.table(
    "Model" = c(
      "Car1",
      "Car1",
      "Car1",
      "Car2",
      "Car2",
      "Car2",
      "Car3",
      "Car3",
      "Car3"
    ),
    "variable" = c(
      "Metric1",
      "Metric2",
      "Metric3",
      "Metric1",
      "Metric2",
      "Metric3",
      "Metric1",
      "Metric2",
      "Metric3"
    ),
    "valeur" = c(1, 2, 3, 4, 5, 6, 7, 8, 9)
  )

Я хочу поместить эту таблицу данных в подмножество на основе названия автомобиля и метрики. Однако я бы хотел избежать использования операторов if, потому что мой код уже очень длинный. Насколько я понял, case_when может быть очень полезным. Я знаю, что формула для таблицы данных с подмножеством верна, поскольку, когда я использую оператор if, он возвращает мне то, что я хочу. Тем не менее, когда я использую case_when, я получаю следующую ошибку:

Error in `[.data.frame`(x, i) : undefined columns selected

Кто-то знает, что я делаю неправильно? Вот мой код:

carName = 'Car1' ##Can be changed
dfCarMetric = case_when(
           carName == 'Car1' ~ dfRawData[which(dfRawData[["Model"]] == carName  &
                                               dfRawData[["variable"]] %in% c("Metric1", "Metric2")), ],
           carName == 'Car2' ~ dfRawData[which(dfRawData[["Model"]] %in% c("Car2", "Car3")  &
                                               dfRawData[["variable"]] == "Metric1"), ]
       )

Я хочу получить это в конце:

carName = 'Car1'
    dfCarMetric
       Model variable valeur
    1:  Car1  Metric1      1
    2:  Car1  Metric2      2

carName = 'Car2'
    dfCarMetric
      Model variable valeur
    4  Car2  Metric1      4
    7  Car3  Metric1      7

Большое спасибо за ваши ответы !!

Ответы [ 2 ]

0 голосов
/ 17 октября 2019

Если вы пытаетесь минимизировать количество условных операторов, вы можете использовать их внутри функции filter, а также из пакета dplyr:

dfCarMetric <- dfRawData %>% 
  filter(
    if (carName == "Car1") 
      Model == carName & variable %in% c("Metric1", "Metric2") 
    else if (carName == "Car2") 
      Model %in% c("Car2", "Car3") & variable == "Metric1")
  )

Функция case_when можетиспользоваться аналогичным образом, хотя и менее обычным ИМХО:

dfCarMetric <- dfRawData %>% 
  filter(case_when(
      carName == "Car1" ~
        Model == carName & variable %in% c("Metric1", "Metric2"), 
      carName == "Car2" ~
        Model %in% c("Car2", "Car3") & variable == "Metric1"
    )
  )
0 голосов
/ 17 октября 2019

Вместо case_when, который я представляю из пакета dplyr, почему бы вам не попробовать вместо него функцию filter, которая лучше подходит для поднабора наборов данных.

library(dplyr)
library(magrittr)

dfRawData <-  data.frame(
    "Model" = c(
      "Car1",
      "Car1",
      "Car1",
      "Car2",
      "Car2",
      "Car2",
      "Car3",
      "Car3",
      "Car3"
    ),
    "variable" = c(
      "Metric1",
      "Metric2",
      "Metric3",
      "Metric1",
      "Metric2",
      "Metric3",
      "Metric1",
      "Metric2",
      "Metric3"
    ),
    "valeur" = c(1, 2, 3, 4, 5, 6, 7, 8, 9)
  )

# Filter
newData <- dfRawData %>% 
  filter((Model =='Car1' & variable %in% c('Metric1', 'Metric2')) |  # Condition 1
                     (Model %in% c('Car2', 'Car3') & variable == 'Metric1')) # Condition 2

Это приводит к выводу, подобному следующему:

 newData
  Model variable valeur
1  Car1  Metric1      1
2  Car1  Metric2      2
3  Car2  Metric1      4
4  Car3  Metric1      7

Вы можете отрегулировать условия filter, чтобы получить именно то подмножество, которое вам нравится, и это должен быть более простой синтаксис, чем case_when.

Использование функции


Чтобы упростить эту задачу и указать carName, вы можете заключить этот конкретный фильтр в простой (хотя и хрупкий)) функция:

myFilterFunction <- function(data, carName = 'Car1', metric = c('Metric1', 'Metric2')) {
  data %>%
    filter(Model %in% carName & variable %in% metric)
}

carName = 'Car1'
myFilterFunction(dfRawData, carName = carName, c('Metric1', 'Metric2'))

carName = c('Car2', 'Car3')
myFilterFunction(dfRawData, carName = carName, c('Metric1'))

с выходами:

  Model variable valeur
1  Car1  Metric1      1
2  Car1  Metric2      2

  Model variable valeur
1  Car2  Metric1      4
2  Car3  Metric1      7
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...