【问题标题】:checking whether at least one value in a dataframe row is bigger than a given row-specific threshold检查数据帧行中的至少一个值是否大于给定的行特定阈值
【发布时间】:2015-07-01 11:57:05
【问题描述】:

这是我正在处理的数据集的小型可重复示例:

set.seed(123)
dat <- as.data.frame( cbind(a=1+round(runif(5), 2), b=round(rnorm(5), 2), high_cutoff=round(1+rnorm(5), 1)) )

数据框是:

     a     b   high_cutoff
   1.29 -1.69         2.3
   1.79  1.24        -0.7
   1.41 -0.11         2.7
   1.88 -0.12         1.5
   1.94  0.18         3.5

我正在尝试按行检查前两列中是否至少有一个值高于第三列中的对应阈值 (假设如果两个值中的任何一个高于截止值,我想存储 1)。

在示例中,我期望找到的是:

   higher_than_cutoff         
0
1
0 
1
0

我一直在尝试使用以下(错误的)代码及其一些变体,但没有取得多大成功:

higher_than_cutoff <- apply( dat[, c("a", "b")], 1, function(x) any(x > dat[, "high_cutoff"]) )

您能否就如何进行操作提供一些建议? 任何帮助都非常感谢

【问题讨论】:

    标签: r apply


    【解决方案1】:

    这是一个可能的矢量化解决方案(如果您只需 TRUE/FALSE 就可以了,您可以删除开头的 +

    +(rowSums(dat[-3L] > dat[, 3L]) > 0)
    ## [1] 0 1 0 1 0
    

    如果你坚持apply,你可以这样做

    apply(dat, 1, function(x) +(any(x[-3] > x[3])))
    ## [1] 0 1 0 1 0
    

    【讨论】:

    • 谢谢大卫!所以它基本上按行汇总所有大于阈值的条目,如果数字> 0,它返回1(否则为0)?很干净,谢谢
    • 是的。您可以将其简化为 rowSums(dat[-3L] &gt; dat[, 3L]) &gt; 0,如果您可以使用 TRUE/FALSE
    • 完美,也感谢 apply 的澄清
    【解决方案2】:

    你可以试试

     as.integer(do.call(pmax,dat[-3]) > dat[,3])
     #[1] 0 1 0 1 0
    

    或者

    ((max.col(dat))!=3)+0L
      #[1] 0 1 0 1 0
    

    【讨论】:

    • max.col 是偷偷摸摸的 :) 非常好。
    • @DavidArenburg 我没有用其他案例测试过它。如果一行具有相同的值,我可能需要提及 max.col(dat, 'first') 左右,这取决于 OP 想要什么
    【解决方案3】:

    可以通过

    得到想要的输出
    higher_than_cutoff <- apply(dat,1,function(x) (max(x[1],x[2])>x[3])*1)
    

    【讨论】:

      【解决方案4】:

      也许我误解了您想要实现的目标,但不使用apply 就可以获得所需的输出,我们只是比较完整的列向量,不需要逐行操作。

      +(dat$a > dat$high_cutoff | dat$b > dat$high_cutoff)
      # [1] 0 1 0 1 0
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-04-05
        • 1970-01-01
        • 2017-11-18
        • 2018-12-08
        • 2018-09-12
        • 2022-01-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多