R中的条件if语句

时间:2016-05-16 05:22:51

标签: r apply

我想知道如何根据其他列的值填充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”,则
  • 表示“更多” 如果“a”小于“b”,则
  • “Less”
  • “如果相等则等于

如下:

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

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

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:4)

这是我的测试看起来非常有效的一个,并不是太复杂:

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将为两次比较返回四种可能性:

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

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

  3. TRUE =秒TRUE.TRUE,因此更多
  4. TRUE =两个jobid,userid,scheduleTime,start_date,end_date,job_frequency,day,status,fileserver,reportid 1,1,15:37:00,2016-05-12,2016-05-15,0,MON-FRI,scheduled,xy,1 ,理论上不可能,除了容错率以下的边缘情况。

答案 1 :(得分:3)

我们可以使用数值方法根据逻辑向量(a > ba==b)创建唯一值,转换为factor,获取numeric存储值转换为numeric,将其替换为vectorc("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))