【问题标题】:R Generating a new variable based on conditional statement applied to many columnsR根据应用于许多列的条件语句生成新变量
【发布时间】:2014-09-30 00:58:08
【问题描述】:

可能有一种明显而优雅的方法可以做到这一点,可能使用 lapply,但我仍在掌握应用命令并且正在努力寻找它。

我有一个如下所示的数据框,除了不是 5 个因子变量,而是有几十个,而不是 10 行,有数百个。

    a<- data.frame("id" = c(1:10),
                   "a1" = factor(c(0,0,1,1,0,1,0,1,0,1)),
                   "a2" = factor(c(0,0,0,0,0,0,0,0,1,0)), 
                   "a3" = factor(c(0,0,0,0,0,1,0,0,0,0)),
                   "a4" = factor(c(0,0,0,0,0,0,0,0,1,1)), 
                   "a5" = factor(c(0,0,0,1,0,0,0,0,0,0)))

我想创建一个新变量,如果 13 列中的任何一列包含特定级别的因子,则该变量为 1。示例数据帧中的等价物将创建一个名为“b”的新变量,如果 a1:a4 的任何列中有一个“1”,则该变量为 1,如下所示。

    a<- data.frame("id" = c(1:10),
                   "a1" = factor(c(0,0,1,1,0,1,0,1,0,1)),
                   "a2" = factor(c(0,0,0,0,0,0,0,0,1,0)), 
                   "a3" = factor(c(0,0,0,0,0,1,0,0,0,0)),
                   "a4" = factor(c(0,0,0,0,0,0,0,0,1,1)), 
                   "a5" = factor(c(0,0,0,1,0,0,0,0,0,0)), 
                   "b"  = c(0,0,1,1,0,1,0,1,1,1))

必须有一种方法可以使用 13 个列位置来执行此操作,而不是为 13 个变量中的每一个变量编写条件 ifthen 语句。

【问题讨论】:

  • 这很明显,您需要重塑数据,使其具有“变量”列,然后是包含“a1”、“a2”、“a3”的因子......和值列,包含所有 0 和 1。请参阅 my answer here 了解为什么这会使此类问题变得更容易。
  • 谢谢。该链接非常有帮助。使用正则表达式识别列效果很好。

标签: r conditional-statements lapply


【解决方案1】:

只需使用rowSums,类似这样:

> as.numeric(rowSums(a[paste0("a", 1:5)] == 1) >= 1)
 [1] 0 0 1 1 0 1 0 1 1 1

【讨论】:

  • (我现在看到 David 的评论包含一个采用非常相似方法的链接...)
  • 我收到“未定义的列已选择”错误。进一步的想法?
  • @user2230555,当然。您正在尝试选择数据集中不存在的列。
  • 甚至(rowSums(a[-1] == 1) &gt; 0)+0
【解决方案2】:

如果你想试试lapply

  Reduce(`|`,lapply(a[,-1], function(x) as.numeric(as.character(x))))+0
  #[1] 0 0 1 1 0 1 0 1 1 1

或者只是

  Reduce(`|`, lapply(a[,-1], `==`, 1)) +0
  #[1] 0 0 1 1 0 1 0 1 1 1

基准测试

set.seed(155)
df <- as.data.frame(matrix(sample(0:1, 5000*1e4, replace=TRUE), ncol=5000))

library(microbenchmark)
f1 <- function() {as.numeric(rowSums(df == 1) >= 1) }
f2 <- function() {Reduce(`|`, lapply(df, `==`, 1)) +0}
f3 <- function() {apply(df == 1, 1, function(x) any(x %in% TRUE))+0}

microbenchmark(f1(), f2(), f3(), unit="relative")
# Unit: relative
# expr       min       lq   median       uq      max neval
# f1() 1.000000 1.000000 1.000000 1.000000 1.000000   100
# f2() 1.040561 1.043713 1.053773 1.032932 1.045067   100
# f3() 2.538287 2.517184 2.825253 2.477225 2.454511   100

【讨论】:

    【解决方案3】:

    您也可以在将矩阵转换为逻辑矩阵后使用any

    > apply(a[grep("a[1-4]", names(a))] == 1, 1, any)+0
    # [1] 0 0 1 1 0 1 0 1 1 1
    

    或者

    > apply(a[grepl("a[1-4]", names(a))] == 1, 1, any)+0
    # [1] 0 0 1 1 0 1 0 1 1 1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-09
      • 1970-01-01
      • 1970-01-01
      • 2017-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-16
      相关资源
      最近更新 更多