我想知道如何根据其他列的值填充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”系列函数来完成这个。
非常感谢任何帮助。
答案 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
将为两次比较返回四种可能性:
FALSE.FALSE
= TRUE
= TRUE.FALSE
,在这种情况下意味着不大或小,因此等于
TRUE
=第一个FALSE.TRUE
,因此
TRUE
=秒TRUE.TRUE
,因此更多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 > b
和a==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))