如何在data.table中同时使用for循环和if条件?
How to use for loop and if conditions together in data.table?
我在 R 中有一个 data.table
dt
是这样的:
ukey time orderType a edge h1 h2
1: 10600877 93003000 Buy 14.12 100 0.002 0.0002
2: 10600188 93003000 Buy 24.29 100 0.003 0.0003
3: 10600995 93003000 Buy 17.23 100 0.003 0.0003
4: 10600262 93003000 Sell 18.89 100 0.002 0.0004
5: 10600399 93003000 Sell 18.66 100 0.004 0.0002
6: 10603260 93003000 Sell 110.39 100 0.003 0.0002
7: 11000004 93003000 Sell 22.98 100 0.002 0.0003
...
我想根据某些条件获得一个名为 check
的新列。我的示例代码如下所示:
for (i in 1:nrow(dt)) {
if (dt[i, a - 1.5 * h1 > 111]) {
dt[, check:= "A"]
break
}
else if (dt[i, a+ edge - 1.3 * h1- 0.3 * h2> 111]) {
dt[, check:= "B"]
break
}
else if (dt[i, a- 1.5 * h1> 80]) {
dt[, check:= "C"]
break
}
else {dt[, check:= "D"]}
}
但是,我的代码运行不佳且效率低下。能给我一些更好的解决方案吗?非常感谢!
您正在寻找的是更快的 ifelse
等价物
子集法
library(data.table)
setDT(dt)
# initialise
dt[, check := "D"]
# faster ifelse
dt[a- 1.5 * h1> 80, check := "C"
][a+ edge - 1.3 * h1- 0.3 * h2> 111, check := "B"
][a - 1.5 * h1 > 111, check := "A"
]
注意后一个子集条件优先。因此,顺序是相反的,即 C、B、A。我们的条件未捕获的任何内容都保留有初始化值,即 D
data.table 的 fcase
# courtesy to SO user @langtang
df[, check := fcase(a - 1.5 * h1 > 111, 'A'
, a + edge - 1.3 * h1 - 0.3 * h2 > 111, 'B'
, a - 1.5 * h1 > 80, 'C'
, default = 'D'
)]
注意使用此方法之前的条件优先。因此,顺序是A、B、C。
您可以尝试使用 dplyr
包中的 case_when
。
dt[, check := case_when((a - 1.5 * h1) > 111 ~ "A",
(a+ edge - 1.3 * h1- 0.3 * h2)> 111 ~ "B",
(a- 1.5 * h1) > 80 ~ "C",
TRUE ~ "D")]
结果如下:
> dt
ukey time orderType a edge h1 h2 check
1: 10600877 93003000 Buy 14.12 100 0.002 2e-04 B
2: 10600188 93003000 Buy 24.29 100 0.003 3e-04 B
3: 10600995 93003000 Buy 17.23 100 0.003 3e-04 B
4: 10600262 93003000 Sell 18.89 100 0.002 4e-04 B
5: 10600399 93003000 Sell 18.66 100 0.004 2e-04 B
6: 10603260 93003000 Sell 110.39 100 0.003 2e-04 B
7: 11000004 93003000 Sell 22.98 100 0.002 3e-04 B
希望有用。
我在 R 中有一个 data.table
dt
是这样的:
ukey time orderType a edge h1 h2
1: 10600877 93003000 Buy 14.12 100 0.002 0.0002
2: 10600188 93003000 Buy 24.29 100 0.003 0.0003
3: 10600995 93003000 Buy 17.23 100 0.003 0.0003
4: 10600262 93003000 Sell 18.89 100 0.002 0.0004
5: 10600399 93003000 Sell 18.66 100 0.004 0.0002
6: 10603260 93003000 Sell 110.39 100 0.003 0.0002
7: 11000004 93003000 Sell 22.98 100 0.002 0.0003
...
我想根据某些条件获得一个名为 check
的新列。我的示例代码如下所示:
for (i in 1:nrow(dt)) {
if (dt[i, a - 1.5 * h1 > 111]) {
dt[, check:= "A"]
break
}
else if (dt[i, a+ edge - 1.3 * h1- 0.3 * h2> 111]) {
dt[, check:= "B"]
break
}
else if (dt[i, a- 1.5 * h1> 80]) {
dt[, check:= "C"]
break
}
else {dt[, check:= "D"]}
}
但是,我的代码运行不佳且效率低下。能给我一些更好的解决方案吗?非常感谢!
您正在寻找的是更快的 ifelse
等价物
子集法
library(data.table)
setDT(dt)
# initialise
dt[, check := "D"]
# faster ifelse
dt[a- 1.5 * h1> 80, check := "C"
][a+ edge - 1.3 * h1- 0.3 * h2> 111, check := "B"
][a - 1.5 * h1 > 111, check := "A"
]
注意后一个子集条件优先。因此,顺序是相反的,即 C、B、A。我们的条件未捕获的任何内容都保留有初始化值,即 D
data.table 的 fcase
# courtesy to SO user @langtang
df[, check := fcase(a - 1.5 * h1 > 111, 'A'
, a + edge - 1.3 * h1 - 0.3 * h2 > 111, 'B'
, a - 1.5 * h1 > 80, 'C'
, default = 'D'
)]
注意使用此方法之前的条件优先。因此,顺序是A、B、C。
您可以尝试使用 dplyr
包中的 case_when
。
dt[, check := case_when((a - 1.5 * h1) > 111 ~ "A",
(a+ edge - 1.3 * h1- 0.3 * h2)> 111 ~ "B",
(a- 1.5 * h1) > 80 ~ "C",
TRUE ~ "D")]
结果如下:
> dt
ukey time orderType a edge h1 h2 check
1: 10600877 93003000 Buy 14.12 100 0.002 2e-04 B
2: 10600188 93003000 Buy 24.29 100 0.003 3e-04 B
3: 10600995 93003000 Buy 17.23 100 0.003 3e-04 B
4: 10600262 93003000 Sell 18.89 100 0.002 4e-04 B
5: 10600399 93003000 Sell 18.66 100 0.004 2e-04 B
6: 10603260 93003000 Sell 110.39 100 0.003 2e-04 B
7: 11000004 93003000 Sell 22.98 100 0.002 3e-04 B
希望有用。