在 R 中使用 grepl 减少嵌套的 if else 语句

Reducing nested if else statements with grepl in R

在 R 中,我有一个数据框,其中有一列 'food',其中包含 100 多个不同的字符串值。

例如:

id<-c("1", "2", "3", "4", "5", "6")
food <- c("X1_", "X2_", "X3_", "X4_", "X5_", "X100_")
df <- data.frame(id, food)

我想根据“食物”列中的字符串创建一个新列“food_final”。我开始使用嵌套的 ifelses 和 grepl 编写代码,但考虑到有 100 多个不同的字符串值,我知道有 100 多个 if elses 绝对是 not 最干净的方法,并且在无论如何,一个人能有多少是有限制的。

到目前为止我尝试过的示例:

df$food_final<-ifelse(grepl("X1_", df$food, ignore.case=TRUE), "1",
                      ifelse(grepl("X2_", df$food, ignore.case=TRUE), "2",
                             ifelse(grepl("X3_", df$food, ignore.case=TRUE), "3",
                                    ifelse(grepl("X4_", df$food, ignore.case=TRUE), "4",
                                        ifelse(grepl("X5_", df$food, ignore.case=TRUE), "5",
                                             ifelse(grepl("X100_", df$food, ignore.case=TRUE), "100", NA))))))

创建这个新列 'food_final' 的最佳方法是什么,而不是使用那么多嵌套的 ifelse 语句?

提前致谢。

sub:

的帮助下,您可能只能使用单行解决方案
df$food_final <- sub("^X(\d+)_$", "\1", df$food)

如果您想提取号码:

df$food_final <- gsub("\D", "", df$food)

df
#  id  food food_final
#1  1   X1_          1
#2  2   X2_          2
#3  3   X3_          3
#4  4   X4_          4
#5  5   X5_          5
#6  6 X100_        100

或者如果有不同的链接,则与嵌套 ifelse.

的操作基本相同
x <- c("1"="X1_", "2"="X2_", "3"="X3_", "4"="X4_", "5"="X5_", "100"="X100_")
apply(sapply(x, grepl, df$food, ignore.case=TRUE), 1, function(y) names(x)[y][1])
#[1] "1"   "2"   "3"   "4"   "5"   "100"

或使用Reduce:

x <- c("1"="X1_", "2"="X2_", "3"="X3_", "4"="X4_", "5"="X5_", "100"="X100_")
Reduce(function(a,b) {
  i <- is.na(a)
  a[i][grepl(x[b], df$food[i], ignore.case=TRUE)] <- b
  a
}, names(x), rep(NA, nrow(df)))
#[1] "1"   "2"   "3"   "4"   "5"   "100"

如果您只是想从字符串中提取数字,我喜欢使用 parse_number from readr

df$food_final<-parse_number(df$food)

您也可以使用 str_extract 只提取数字:

library(stringr)
df$food_final <- str_extract(df$food, "\d+")

我们可以使用 tidyr 包中的 extract_numeric

library(dplyr)
library(tidyr)

df %>% 
  mutate(final_food = extract_numeric(food))

输出:

  id  food final_food
1  1   X1_          1
2  2   X2_          2
3  3   X3_          3
4  4   X4_          4
5  5   X5_          5
6  6 X100_        100