R中的条件if语句

Conditional if statement in R

我想知道如何根据其他列的值填充 data.frame 或 data.table 中的列。

例如:

data.table(a = c(1:5), b = c(5:1), c = rep("",5))
 a b c
 1 5  
 2 4  
 3 3  
 4 2  
 5 1  

我想将 c 填充到:

如下:

a b c
1 5 "Less" 
2 4 "Less" 
3 3 "Equal"
4 2 "More"
5 1 "More"

我知道这可以通过带有多个 if 语句的 for 循环来完成,但是我有一个非常大的数据集,我想使用 "Apply" 系列函数来完成。

如有任何帮助,我们将不胜感激。

我们可以使用数值方法根据逻辑向量(a > ba==b)创建唯一值,转换为factor,得到numeric存储通过转换为 numeric 的值,将其替换为 vector (c("Less", "More", "Equal")) 中的元素并将其分配 (:=) 为 'c'.

dt1[, c :=c("Less", "More", "Equal")[as.numeric(factor(1+2*(a>b) + 4*(a==b)))]]
dt1
#   a b     c
#1: 1 5  Less
#2: 2 4  Less
#3: 3 3 Equal
#4: 4 2  More
#5: 5 1  More

或者我们可以使用嵌套 ifelse 来获得预期的输出。

dt1[, c:= ifelse(a>b, "More", ifelse(a<b, "Less", "Equal"))]

或者另一种选择是使用 Reduce/max.col/pmax 获取数字索引并将其替换为第一种方法中所示的字符向量。

dt1[,  c:= c("Equal", "Less", "More")[pmax(max.col(.SD),
                         3*Reduce(`==`, .SD))], .SDcols = a:b]

数据

dt1 <-  data.table(a = c(1:5), b = c(5:1), c = rep("",5))

根据我的测试,这是一个非常高效的方法,而且并不过分复杂:

dt1[, c := c("less","equal","more")[max.col(setDT(.(a < b, a==b, a > b)))] ]

使用 interaction 的另一种选择,它在简化代码方面与我所能做的一样好:

dt1[, c := c("equal","less","more")[interaction(a < b, a > b)] ]

#   a b     c
#1: 1 5  less
#2: 2 4  less
#3: 3 3 equal
#4: 4 2  more
#5: 5 1  more

这是有效的,因为 interaction 将 return 两种比较的四种可能性:

  1. FALSE.FALSE = 两者都不 TRUE,在这种情况下意味着不大于或小于,因此等于

  2. TRUE.FALSE = 第一个 TRUE,因此少

  3. FALSE.TRUE = 第二个 TRUE,因此更多
  4. TRUE.TRUE = 两者都 TRUE,理论上不可能,除了低于误差容限的边缘情况。