分隔 R data.table 中的正值和负值(多列)
Separating positive and negative values in R data.table (many columns)
我想知道如何通过 data.table 中的符号拆分多个列。具体来说,假设我们有:
library(data.table)
DT = data.table(x = c(-1,-2,1,3),
z = c(-1,-1,-1,-1))
我想创建一个名为 DT_new
的新 data.table,它看起来像:
DT_new
x z x_pos x_neg z_pos z_neg
1: -1 -1 0 1 0 1
2: -2 -1 0 2 0 1
3: 1 -1 1 0 0 1
4: 3 -1 3 0 0 1
我这样做的原因是我想在回归中分离出正变量和负变量。手动执行其中一些操作很容易。但是我有数百个变量要应用此技术。所以我希望有一个“SDcols”解决方案。
谢谢!
也许:
library(data.table)
DT = data.table(x = c(-1,-2,1,3),
z = c(-1,-1,-1,-1))
col_nms <- c('x', 'z')
pos_nms <- paste0(col_nms, '_pos')
neg_nms <- paste0(col_nms, '_neg')
DT[, c(pos_nms) := lapply(.SD, function(.x) fifelse(.x > 0, .x, 0)), .SDcols = c('x', 'z')]
DT[, c(neg_nms) := lapply(.SD, function(.x) fifelse(.x < 0, -.x, 0)), .SDcols = c('x', 'z')]
DT
#> x z x_pos z_pos x_neg z_neg
#> 1: -1 -1 0 0 1 1
#> 2: -2 -1 0 0 2 1
#> 3: 1 -1 1 0 0 1
#> 4: 3 -1 3 0 0 1
由 reprex package (v2.0.1)
于 2021-11-27 创建
无需使用 .SDcols ;-) 请在下面找到一个代表:
- 代码
DT[,`:=` (x_pos = fifelse(x>0, x, 0),
x_neg = fifelse(x<0, abs(x), 0),
z_pos = fifelse(z>0, z, 0),
z_neg = fifelse(z<0, abs(z), 0))][]
- 输出
x z x_pos x_neg z_pos z_neg
1: -1 -1 0 1 0 1
2: -2 -1 0 2 0 1
3: 1 -1 1 0 0 1
4: 3 -1 3 0 0 1
作为您评论的后续行动
请在下面找到代表。
- 代码
vars <- c("x","z")
suffix <- c("_pos", "_neg")
DT[, CJ(vars, suffix, sorted = FALSE)[, paste0(vars, suffix)] := .(fifelse(x>0, x, 0),
fifelse(x<0, abs(x), 0),
fifelse(z>0, z, 0),
fifelse(z<0, abs(z), 0))][]
- 输出
#> x z x_pos x_neg z_pos z_neg
#> 1: -1 -1 0 1 0 1
#> 2: -2 -1 0 2 0 1
#> 3: 1 -1 1 0 0 1
#> 4: 3 -1 3 0 0 1
由 reprex package (v2.0.1)
于 2021-11-28 创建
我们可以使用 across
和 case_when
:
library(dplyr)
DT %>%
mutate(across(everything(), ~case_when(
. < 0 ~ 0,
TRUE ~ .), .names = "{col}_pos")) %>%
mutate(across(-contains("pos"), ~case_when(
. < 0 ~ abs(.),
TRUE ~ 0), .names = "{col}_neg"))
x z x_pos z_pos x_neg z_neg
1: -1 -1 0 0 1 1
2: -2 -1 0 0 2 1
3: 1 -1 1 0 0 1
4: 3 -1 3 0 0 1
library(data.table)
DT = data.table(x = c(-1,-2,1,3),
z = c(-1,-1,-1,-1))
vars <- names(DT)
DT <- DT[, sapply(.SD, function(j){
list(ifelse(j<0, 0, j),
ifelse(j>0, 0, j))
})]
setnames(DT, paste(rep(vars, each=2), c("_pos", "_neg"), sep=""))
另一个 dplyr 选项
library(data.table)
library(dplyr, warn.conflicts = F)
DT <- data.table(x = c(-1, -2, 1, 3),
z = c(-1, -1, -1, -1))
DT %>%
mutate(across(everything(), list(
pos = ~ if_else(. > 0, ., 0),
neg = ~ if_else(. < 0, -., 0)
)))
#> x z x_pos x_neg z_pos z_neg
#> 1: -1 -1 0 1 0 1
#> 2: -2 -1 0 2 0 1
#> 3: 1 -1 1 0 0 1
#> 4: 3 -1 3 0 0 1
由 reprex package (v2.0.1)
于 2021-11-27 创建
如果您想使用此语法但在幕后执行 data.table 操作,您可以使用 tidytable
.
library(data.table)
library(tidytable, warn.conflicts = F)
DT <- data.table(x = c(-1, -2, 1, 3),
z = c(-1, -1, -1, -1))
DT %>%
mutate.(across.(everything(), list(
pos = ~ if_else(. > 0, ., 0),
neg = ~ if_else(. < 0, -., 0)
)))
#> # A tidytable: 4 × 6
#> x z x_pos x_neg z_pos z_neg
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 -1 -1 0 1 0 1
#> 2 -2 -1 0 2 0 1
#> 3 1 -1 1 0 0 1
#> 4 3 -1 3 0 0 1
由 reprex package (v2.0.1)
于 2021-11-27 创建
我想知道如何通过 data.table 中的符号拆分多个列。具体来说,假设我们有:
library(data.table)
DT = data.table(x = c(-1,-2,1,3),
z = c(-1,-1,-1,-1))
我想创建一个名为 DT_new
的新 data.table,它看起来像:
DT_new
x z x_pos x_neg z_pos z_neg
1: -1 -1 0 1 0 1
2: -2 -1 0 2 0 1
3: 1 -1 1 0 0 1
4: 3 -1 3 0 0 1
我这样做的原因是我想在回归中分离出正变量和负变量。手动执行其中一些操作很容易。但是我有数百个变量要应用此技术。所以我希望有一个“SDcols”解决方案。
谢谢!
也许:
library(data.table)
DT = data.table(x = c(-1,-2,1,3),
z = c(-1,-1,-1,-1))
col_nms <- c('x', 'z')
pos_nms <- paste0(col_nms, '_pos')
neg_nms <- paste0(col_nms, '_neg')
DT[, c(pos_nms) := lapply(.SD, function(.x) fifelse(.x > 0, .x, 0)), .SDcols = c('x', 'z')]
DT[, c(neg_nms) := lapply(.SD, function(.x) fifelse(.x < 0, -.x, 0)), .SDcols = c('x', 'z')]
DT
#> x z x_pos z_pos x_neg z_neg
#> 1: -1 -1 0 0 1 1
#> 2: -2 -1 0 0 2 1
#> 3: 1 -1 1 0 0 1
#> 4: 3 -1 3 0 0 1
由 reprex package (v2.0.1)
于 2021-11-27 创建无需使用 .SDcols ;-) 请在下面找到一个代表:
- 代码
DT[,`:=` (x_pos = fifelse(x>0, x, 0),
x_neg = fifelse(x<0, abs(x), 0),
z_pos = fifelse(z>0, z, 0),
z_neg = fifelse(z<0, abs(z), 0))][]
- 输出
x z x_pos x_neg z_pos z_neg
1: -1 -1 0 1 0 1
2: -2 -1 0 2 0 1
3: 1 -1 1 0 0 1
4: 3 -1 3 0 0 1
作为您评论的后续行动
请在下面找到代表。
- 代码
vars <- c("x","z")
suffix <- c("_pos", "_neg")
DT[, CJ(vars, suffix, sorted = FALSE)[, paste0(vars, suffix)] := .(fifelse(x>0, x, 0),
fifelse(x<0, abs(x), 0),
fifelse(z>0, z, 0),
fifelse(z<0, abs(z), 0))][]
- 输出
#> x z x_pos x_neg z_pos z_neg
#> 1: -1 -1 0 1 0 1
#> 2: -2 -1 0 2 0 1
#> 3: 1 -1 1 0 0 1
#> 4: 3 -1 3 0 0 1
由 reprex package (v2.0.1)
于 2021-11-28 创建我们可以使用 across
和 case_when
:
library(dplyr)
DT %>%
mutate(across(everything(), ~case_when(
. < 0 ~ 0,
TRUE ~ .), .names = "{col}_pos")) %>%
mutate(across(-contains("pos"), ~case_when(
. < 0 ~ abs(.),
TRUE ~ 0), .names = "{col}_neg"))
x z x_pos z_pos x_neg z_neg
1: -1 -1 0 0 1 1
2: -2 -1 0 0 2 1
3: 1 -1 1 0 0 1
4: 3 -1 3 0 0 1
library(data.table)
DT = data.table(x = c(-1,-2,1,3),
z = c(-1,-1,-1,-1))
vars <- names(DT)
DT <- DT[, sapply(.SD, function(j){
list(ifelse(j<0, 0, j),
ifelse(j>0, 0, j))
})]
setnames(DT, paste(rep(vars, each=2), c("_pos", "_neg"), sep=""))
另一个 dplyr 选项
library(data.table)
library(dplyr, warn.conflicts = F)
DT <- data.table(x = c(-1, -2, 1, 3),
z = c(-1, -1, -1, -1))
DT %>%
mutate(across(everything(), list(
pos = ~ if_else(. > 0, ., 0),
neg = ~ if_else(. < 0, -., 0)
)))
#> x z x_pos x_neg z_pos z_neg
#> 1: -1 -1 0 1 0 1
#> 2: -2 -1 0 2 0 1
#> 3: 1 -1 1 0 0 1
#> 4: 3 -1 3 0 0 1
由 reprex package (v2.0.1)
于 2021-11-27 创建如果您想使用此语法但在幕后执行 data.table 操作,您可以使用 tidytable
.
library(data.table)
library(tidytable, warn.conflicts = F)
DT <- data.table(x = c(-1, -2, 1, 3),
z = c(-1, -1, -1, -1))
DT %>%
mutate.(across.(everything(), list(
pos = ~ if_else(. > 0, ., 0),
neg = ~ if_else(. < 0, -., 0)
)))
#> # A tidytable: 4 × 6
#> x z x_pos x_neg z_pos z_neg
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 -1 -1 0 1 0 1
#> 2 -2 -1 0 2 0 1
#> 3 1 -1 1 0 0 1
#> 4 3 -1 3 0 0 1
由 reprex package (v2.0.1)
于 2021-11-27 创建