我正在使用R中的data.frame转换为data.table以获得更好的性能。转换代码的主要部分之一是应用自定义函数,从data.frame应用到在data.table中使用它。
假设我有一个简单的数据表,dt1。
x y z---header
1 9 j
4 1 n
7 1 n
尝试根据x,y,z的值计算dt1中的另一个新列 我尝试了两种方法,它们都给出了正确的结果,但是更快的方法会发出警告。因此,在使用更快的版本转换现有代码之前,请确保警告并不严重。
(1) dt1[,a:={if((x<1) & (y>3) & (j == "n")){6} else {7}}]
(2) dt1[,a:={if((x<1) & (y>3) & (j == "n")){6} else {7}}, by = 1:nrow(x)]
版本1运行速度比版本2快,但会发出警告“条件长度> 1且仅使用第一个元素” 但结果很好。 第二个版本略慢,但没有给出警告。 一旦我开始编写复杂的函数,我想确保版本1不会产生不稳定的结果。
请将问题视为通用问题,以便运行用户定义的函数,该函数想要访问给定行中的不同列值并计算该行的新列值。
感谢您的帮助。
答案 0 :(得分:3)
如果'x','y'和'z'是'dt1'的列,请尝试向量化ifelse
dt1[, a:=ifelse(x<1 & y >3 & z=='n', 6, 7)]
或者用7创建'a',然后根据逻辑索引将6分配给'a'。
dt1[, a := 7][x<1 & y >3 & z=='n', a:=6][]
使用功能
getnewvariable <- function(v1, v2, v3){
ifelse(v1 <1 & v2 >3 & v3=='n', 6, 7)
}
dt1[, a:=getnewvariable(x,y,z)][]
df1 <- structure(list(x = c(0L, 1L, 4L, 7L, -2L), y = c(4L, 9L, 1L,
1L, 5L), z = c("n", "j", "n", "n", "n")), .Names = c("x", "y",
"z"), class = "data.frame", row.names = c(NA, -5L))
dt1 <- as.data.table(df1)