使用if {else if> else语句在R

时间:2016-06-13 09:12:33

标签: r if-statement vectorization

我正在尝试获取因子X的向量,其值取决于数据帧中的两列(可能更多)。所以它可以有两个以上的级别。

有一种简单的方法可以使用C / C ++来执行它 - 就像for循环中的条件语句一样。让我们说,如果我正在数据框X中的两个布尔列Col1Col2中的值构建MATRIX,我可以轻松地执行:{/ p>

X=vector()
for ( i in 1:nrow(MATRIX)) {
  if (MATRIX$Col1[i]==1 && MATRIX$Col2[i]==1) { 
    X[i] = "both"
  } else if (MATRIX$Col1[i]==1) {
    X[i] = "col1"
  } else if (MATRIX$Col2[i]==1) {
    X[i] = "col2"
  } else {
    X[i] = "none"
  }
}

问题是,在大型数据帧中,它需要花费很多时间才能运行。我应该使用矢量化来优化这一点,但我看不到方法,因为 * apply ifelse 任何的功能似乎不合适help就是这样一个任务,结果不是布尔值。

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

以下是几种方法:

与您现有方法最相似的是:

X <- ifelse(MATRIX$Col1==1,
            ifelse(MATRIX$Col2==1,"both","col1"),
            ifelse(MATRIX$Col2==1,"col2","none"))

可以稍快一些:

x <- rep(NA,nrow(MATRIX))
x[MATRIX$Col1[i]==1 && MATRIX$Col2[i]==1] <- "both"
x[MATRIX$Col1[i]==1 && !MATRIX$Col2[i]==1] <- "col1"
x[!MATRIX$Col1[i]==1 && MATRIX$Col2[i]==1] <- "col2"
x[!MATRIX$Col1[i]==1 && !MATRIX$Col2[i]==1] <- "none"

但是很难看出代码是否涵盖了所有案例

注意:

  • 看起来MATRIX确实是data.frame;学习成为 精确的数据类型在调试代码时确实很有帮助。
  • 如果MATRIX$Col1确实是布尔值,您可以放弃==1比较, 通过将矩阵转换为数字然后再浪费时间 测试平等。
  • 对我而言,最透明的方法是创造 一个小的data.frame,可能的值为Col1,Col2和 预期输出,并将其与现有的data.frame合并,但是 这可能效率不高。

答案 1 :(得分:2)

我们可以使用factor

# dummy data
set.seed(1)
MATRIX <- data.frame(Col1 = sample(0:1, 10, replace = TRUE),
                     Col2 = sample(0:1, 10, replace = TRUE))

# using factor
cbind(MATRIX,
      X = factor(paste(as.numeric(MATRIX$Col1 == 1),
                       as.numeric(MATRIX$Col2 == 1), sep = "_"),
                 levels = c("0_0", "0_1", "1_0", "1_1"),
                 labels = c("none", "col2", "col1", "both")))

#     Col1 Col2    X
#  1     0    0 none
#  2     0    0 none
#  3     1    1 both
#  4     1    0 col1
#  5     0    1 col2
#  6     1    0 col1
#  7     1    1 both
#  8     1    1 both
#  9     1    0 col1
# 10     0    1 col2