【问题标题】:Create a vector using if...else if...else statements in R在 R 中使用 if...else if...else 语句创建向量
【发布时间】:2016-10-13 15:21:25
【问题描述】:

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

有一种简单的方法可以在 for 循环中使用类似 C/C++ 的条件语句来执行它。假设,如果我从数据框MATRIX 中的两个布尔列Col1Col2 中的值构造X,我可以轻松地做到这一点:

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"
  }
}

问题显然在于,在大型数据帧中运行需要很长时间。我应该使用矢量化来优化这一点,但我看不到方法,因为 *applyifelseany 之类的功能似乎没有help 就是这样一个任务,结果不是布尔值。

有什么想法吗?

【问题讨论】:

  • 只需将 if... else 转换为 ifelse() 并删除 for 循环。

标签: r if-statement vectorization


【解决方案1】:

我们可以使用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

【讨论】:

    【解决方案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 比较, 通过将矩阵转换为数字然后 测试平等。
    • 对我来说,最透明的方法是创建 一个带有 Col1、Col2 和 Col1 可能值的小数据框 预期的输出,并将其与现有的 data.frame 合并,但是 这可能效率不高。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-27
      • 2020-10-29
      • 2019-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-23
      • 1970-01-01
      相关资源
      最近更新 更多