如果给出以下数据表,并且我们希望将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 < x2
,那么compare == 1
等等
现在在我的例子中,我有更多的列来比较x1和。有没有办法更简洁地写这个,即没有嵌套的ifelse?
答案 0 :(得分:5)
我们可以使用Map
max.col
和data.table
来执行此操作
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
答案 1 :(得分:5)
这节省了一些打字并且易于阅读。
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]应替换为相关的列集。