使用条件语句时如何利用 R 向量化? (替代循环)

How to take advantage of R vectorization when using conditional statements? (alternative to looping)

我正在尝试根据数据框中的几个条件对数据进行分组。目前,我正在使用一个效用函数来执行此操作,然后对其进行循环,但由于 R 是矢量化的,我想知道是否有更像 R 的方法来执行此操作?

Items.Ordered <- CMdata$Items.Ordered

orderGroup <- function(Items.Ordered) {
  Items.Ordered <- as.numeric(Items.Ordered)

  if (CMdata$Items.Ordered == 0) {
    return ("NONE")
  } else if (CMdata$Items.Ordered > 0 & CMdata$Items.Ordered <= 3) {
    return ("SMALL")
  } else if (CMdata$Items.Ordered > 3 & CMdata$Items.Ordered <= 8) {
    return ("MEDIUM")
  } else if (CMdata$Items.Ordered > 8) {
    return ("LARGE")
  } else {
    return ("OTHER")
  }
}


Order.Type <- NULL
for (i in 1:nrow(CMdata)) {
  Order.Type <- c(Order.Type, orderGroup(CMdata[i,"Items.Orderd"]))
}
CMdata$Order.Type <- as.factor(Order.Type)

我认为您的程序没有按预期运行。 您将单个值传递给 orderGroup 函数, 不是向量, 而且这些条件无论如何都不适用于向量。

我想你真正的意思是这样的:

orderGroup <- function(value) {
  if (value == 0) {
    "NONE"
  } else if (value > 0 & value <= 3) {
    "SMALL"
  } else if (value > 3 & value <= 8) {
    "MEDIUM"
  } else if (value > 8) {
    "LARGE"
  } else {
    "OTHER"
  }
}

为了让它更实用, 您可以使用 sapply 而不是循环,如下所示:

CMdata$Order.Type <- as.factor(sapply(CMdata$Items.Ordered, orderGroup))

一种可能的解决方案是对您的列执行 cut,然后根据每个值所属的范围重新标记该因子。例如:

假设您的 CMdata 包含如下列:

CMdata
   Items.Ordered
1             NA
2              0
3              1
4              2
5              3
6              4
7              5
8              6
9              7
10             8
11             9
12            10
13            NA

您可以cutfactor根据您的情况:

CMdata$Order.Type <- factor(cut(CMdata$Items.Ordered, breaks = c(-Inf, 0, 3, 8, Inf)), 
                            exclude = NULL, 
                            labels = c("NONE", "SMALL", "MEDIUM", "LARGE", "OTHER")) 
CMdata
   Items.Ordered Order.Type
1             NA      OTHER
2              0       NONE
3              1      SMALL
4              2      SMALL
5              3      SMALL
6              4     MEDIUM
7              5     MEDIUM
8              6     MEDIUM
9              7     MEDIUM
10             8     MEDIUM
11             9      LARGE
12            10      LARGE
13            NA      OTHER