R 缩短嵌套的ifelse

R 缩短嵌套的ifelse,r,if-statement,data.table,R,If Statement,Data.table,如果给出了以下数据表,并且我们希望将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),

如果给出了以下数据表,并且我们希望将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))))]
set.seed(1)
库(数据表)

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

TDT[,compare:={d1这节省了一点打字时间,而且易于阅读

TDT[, compare := dplyr::case_when(
      x1 < x2 ~ 1,
      x1 < x3 ~ 2,
      x1 < x4 ~ 3,
      x1 < x5 ~ 4,
      TRUE ~ 5)]
TDT[,compare:=dplyr::case\u当(
x1
如果您有太多的列,不想按名称一一提及,那么您可以使用:

apply(TDT, 1, function (x) which(x[1] < x[2:5])[1]) 
apply(TDT,1,函数(x),其中(x[1]

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

在您的示例中,它给出的是all FALSE,请提供一个示例,给出所有可能性
max.col(TDT$x1
@user20650,这是一个聪明的选择。我喜欢它it@user20650我想可以改成
TDT[,compare:=max.col(x1
我尝试使用
c(.SD,Inf)
但不知怎的,它返回了errorgood stuff@Akrun,这看起来更像it@user3032689我改变了答案,我想这是一个更干净的选择,可以代替
Map()
/
max.col()
/
Reduce
是使用一个简单而灵活的循环——例如,类似于
compare=rep_len(长度(TDT),nrow(TDT));for(长度为i(TDT):2)compare[TDT[[i]]>TDT[[1]]=i-1L
看起来有效我以前从未使用过那个
:=
操作符。你能简单解释一下它在这里的作用吗?根据在线文档,我也不太清楚……我也不太清楚。有点疯狂的
数据.表格
的东西。我认为它创建了一个新的列。不过很酷,谢谢!我读了它a:ata.table列就位(通过引用),以避免在替换或重新分配部分数据集时出现任何类型的浅拷贝或深拷贝。您可以这样使用它:
DT[,c(“colA”,“colB”,…):=list(valA,valB…)
@patrick请参见页面