Проблема с вложенным оператором ifelse в R - PullRequest
0 голосов
/ 28 мая 2020

Я пытаюсь запустить вложенный оператор ifelse в R. Вот посмотрите на структуру моих данных с помощью функции glimpse () из tidyverse:

Rows: 22,104
Columns: 9
$ `Formation/Locality`    <chr> "Montmartre", "Montmartre", "Montmartre", "Fur", "Me...
$ Location                <chr> "Ile-de-France Region, France", "Ile-de-France Regio...
$ Environment             <chr> "terrestrial", "terrestrial", "terrestrial", "offsho...
$ `Palaeolongitude(N/-S)` <dbl> 47.4, 47.4, 47.4, 52.3, 46.9, 42.9, 47.5, 46.9, 46.2...
$ `Palaeolatitude(E/-W)`  <dbl> 1.6, 1.6, 1.6, 5.4, 4.8, 1.9, -5.2, 4.8, -93.6, -111...
$ TaxonomicLevel          <chr> "Order", "Order", "Order", "Order", "Order", "Order"...
$ TaxonomicName           <chr> "Upupiformes", "Upupiformes", "Upupiformes", "Trogon...
$ MinMax                  <chr> "MaxMa", "MaxMa", "MaxMa", "MaxMa", "MaxMa", "MaxMa"...
$ Age                     <dbl> 37.2, 37.2, 37.2, 55.8, 48.6, 37.2, 48.6, 48.6, 55.8...

Я пытаюсь получить R для просмотра столбца Age и, если значение находится в определенном диапазоне, для помещения названия геологического возраста в новый столбец с именем AgeName. Если значение выходит за пределы диапазона, я хочу, чтобы оно перешло в следующий возрастной диапазон и так далее, и так далее. Вот мой код:

pbdb_tidyish$AgeName <- ifelse(56>=pbdb_tidyish$Age&&47.8<pbdb_tidyish$Age,
                               "Ypresian",
                               ifelse(47.8>=pbdb_tidyish$Age&&41.2<pbdb_tidyish$Age,
                                      "Lutetian",
                                      ifelse(41.2>=pbdb_tidyish$Age&&37.8<pbdb_tidyish$Age,
                                             "Bartonian",
                                             ifelse(37.8>=pbdb_tidyish$Age&&33.9<=pbdb_tidyish$Age,
                                                    "Priabonian",NA))))

Когда я запускаю этот код, он создает новый столбец, но заполняет весь столбец "Priabonian", поэтому теперь набор данных выглядит следующим образом:

Rows: 22,104
Columns: 10
$ `Formation/Locality`    <chr> "Montmartre", "Montmartre", "Montmartre", "Fur", "Me...
$ Location                <chr> "Ile-de-France Region, France", "Ile-de-France Regio...
$ Environment             <chr> "terrestrial", "terrestrial", "terrestrial", "offsho...
$ `Palaeolongitude(N/-S)` <dbl> 47.4, 47.4, 47.4, 52.3, 46.9, 42.9, 47.5, 46.9, 46.2...
$ `Palaeolatitude(E/-W)`  <dbl> 1.6, 1.6, 1.6, 5.4, 4.8, 1.9, -5.2, 4.8, -93.6, -111...
$ TaxonomicLevel          <chr> "Order", "Order", "Order", "Order", "Order", "Order"...
$ TaxonomicName           <chr> "Upupiformes", "Upupiformes", "Upupiformes", "Trogon...
$ MinMax                  <chr> "MaxMa", "MaxMa", "MaxMa", "MaxMa", "MaxMa", "MaxMa"...
$ Age                     <dbl> 37.2, 37.2, 37.2, 55.8, 48.6, 37.2, 48.6, 48.6, 55.8...
$ AgeName                 <chr> "Priabonian", "Priabonian", "Priabonian", "Priabonia...

Кто-нибудь знает, где я ошибаюсь? Я думаю, он просто смотрит на первое значение Age, запускает оператор ifelse, а затем заполняет весь столбец результатом этого, а не переходит к следующей строке.

Спасибо,

Каролина

Ответы [ 3 ]

3 голосов
/ 28 мая 2020

Без данных неясно, является ли это единственной ошибкой, но вы не должны использовать здесь &&, поскольку он не векторизован. Это означает, что он проверяет только значение в первой строке, возвращает либо TRUE, либо FALSE, основываясь только на этом единственном наблюдении, и повторяет это значение.

Вместо этого используйте &.

Для сравнения см. этот ответ

1 голос
/ 28 мая 2020

Вы уже используете тидиверс, вам следует ознакомиться с case_when:

pbdb_tidyish <- pbdb_tidyish %>%
  mutate(AgeName = case_when(
    (Age >= 33.9 & Age <= 37.8) ~ 'Priabonian',
    (Age > 37.8 & Age <= 41.2) ~ 'Bartonian',
    (Age > 41.2 & Age <= 47.8) ~ 'Lutetian',
    (Age > 47.8 & Age <= 56) ~ 'Ypresian',
  ))
1 голос
/ 28 мая 2020

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

cut(pdb$tidyish, breaks = c(33.9, 37.8, 41.2, 47.8, 56),
    labels = c("Priabonian", "Bartonian", "Lutetian", "Ypresian"))

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...