R中嵌套ifelse语句的问题

Trouble with nested ifelse statement in R

我正在尝试 运行 R 中的嵌套 ifelse 语句。下面是使用 tidyverse 中的 glimpse() 函数查看我的数据结构:

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 值,运行ning ifelse 语句然后用它的结果填充整个列,而不是移动到下一行。

谢谢,

卡罗莱纳州

没有数据,不清楚这是否是唯一的错误,但您不应在此处使用 &&,因为它未矢量化。这意味着,它只检查第一行中的值,returns TRUEFALSE,仅基于此单一观察,并回收此值。

改用&

有关比较,请参阅 this answer

我认为每当您发现自己正在编写嵌套的 ifelse 语句时,您应该停下来问问自己是否有更好的方法来实现您想要做的事情。例如,以下单个函数调用可以实现您想要实现的目标,并且更易于理解和维护:

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

您已经在使用 tidyverse,您应该熟悉一下 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',
  ))