【问题标题】:Shorten nested ifelse缩短嵌套 ifelse
【发布时间】:2017-03-27 11:25:15
【问题描述】:

如果给出以下数据表,我们想将 x1 与 x2 到 x5 进行比较,则可以使用以下数据:

set.seed(1)
library(data.table)
TDT <- data.table(x1 = round(rnorm(100,0.75,0.3),2),
                  x2 = round(rnorm(100,0.75,0.3),2),
                  x3 = round(rnorm(100,0.75,0.3),2),
                  x4 = round(rnorm(100,0.75,0.3),2),
                  x5 = round(rnorm(100,0.75,0.3),2))

TDT[,compare := ifelse(x1 < x2,1,ifelse(x1 < x3,2,ifelse(x1 < x4,3,ifelse(x1 < x5,4,5))))]

所以如果x1 &lt; x2,那么compare == 1,等等。

现在在我的示例中,我有更多的列可以与 x1 进行比较。有什么方法可以更简洁地写这个,即没有嵌套 ifelse?

【问题讨论】:

  • 在你的例子中,它给出的都是 FALSE,请提供一个给出所有可能性的例子
  • max.col(TDT$x1 &lt; cbind(TDT[, -1, with=F], Inf), "first")
  • @user20650 这是一个聪明的选择。我喜欢它
  • @user20650 我认为它可以更改为TDT[, compare := max.col(x1 &lt; data.table(.SD, Inf), "first"), .SDcols = x2:x5] 我正在尝试使用c(.SD, Inf) 但不知何故它返回错误
  • 好东西@Akrun,看起来有点像

标签: r if-statement data.table


【解决方案1】:

这样可以节省一些打字时间,并且易于阅读。

TDT[, compare := dplyr::case_when(
      x1 < x2 ~ 1,
      x1 < x3 ~ 2,
      x1 < x4 ~ 3,
      x1 < x5 ~ 4,
      TRUE ~ 5)]

如果您有很多列,不想一一提到它们的名称,那么您可以使用:

apply(TDT, 1, function (x) which(x[1] < x[2:5])[1]) 

其中 x[2:5] 应替换为相关的列集。

【讨论】:

  • 我以前从未使用过:= 运算符。你能简要解释一下它在这里的作用吗?根据在线文档,我不太清楚...
  • 我也没有。有点疯狂data.table 的东西。我认为它会创建一个新列。
  • 非常感谢!我阅读了little more::= 操作符就地更新 data.table 列(通过引用) 以避免在替换或重新分配部分数据集。你可以这样使用它:DT[, c("colA", "colB", ...) := list(valA, valB, ...)]
  • @patrick 查看Getting Started 页面
【解决方案2】:

我们可以在data.table 中使用Map 和max.col 来做到这一点

TDT[, compare := {d1 <- as.data.table(Map(function(x) x1 < x, .SD))
       max.col(d1, "first") *(c(5, 1)[((Reduce(`+`, d1)!=0)+1)])}, .SDcols = x2:x5]

#OP's code
v1 <- TDT[, ifelse(x1 < x2,1,ifelse(x1 < x3,2,ifelse(x1 < x4,3,ifelse(x1 < x5,4,5))))]
identical(v1, TDT$compare)
#[1] TRUE

【讨论】:

  • @user3032689 我改了答案
  • 我想Map()/max.col()/Reduce 的更简洁的替代方案是使用简单而灵活的循环——例如compare = rep_len(length(TDT), nrow(TDT)); for(i in length(TDT):2) compare[TDT[[i]] &gt; TDT[[1]]] = i - 1L 之类的东西看起来有效
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多