R – mutate condition in huge data.frame
所以我有非常大的数据集(>1000 obs. of >15000 variables),我不想用 1 替换所有值 >1 并保持其余部分不变。
示例数据:
1
2 3 4 5 6 7 8 9 10 11 12 13 |
data <- data.frame(a = 1:10, b = -1:-10, c = letters[1:10])
a b c |
这是我的dplyr方法:
1
2 3 4 5 6 7 |
data %>% mutate_if(is.numeric,
funs( case_when( . >= 1 ~ 1, TRUE ~ as.double(.)) ) ) |
这需要很长时间才能处理原始数据。知道如何加快速度吗? data.table?
- 如果它提高了性能,你能检查一下吗? data[data > 1] <- 1
- 不要使用 case_when,以防您只有一个案例。
- 你说得对!这只是一个例子。将添加其他 case_when。
这个带有 data.table 的解决方案似乎有效,公平地说,它给出了一个 warning():
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
library(data.table)
library(purrr) num_cols <- colnames(data)[map_lgl(data, is.numeric)] # select only the numerics data[, (num_cols):= lapply(.SD, function(x) { |
Warning message: In [.data.table(data, , :=((num_cols),
lapply(.SD, function(x) { : Supplied 2 columns to be assigned a list
(length 3) of values (1 unused)
使用的数据:
1
|
data <- data.table(a = 1:10, aa = 1:10, b = -1:-10, c = letters[1:10])
|
基准:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
microbenchmark::microbenchmark(
dplyr = data %>% mutate_if(is.numeric, funs( case_when( . >= 1 ~ 1, TRUE ~ as.double(.)) ) ), datatable = data[, (num_cols):= lapply(.SD, function(x) { x[x>1] = 1 x}) ], times = 100 ) # Unit: microseconds |
公平地说,更新 Ronak Shah 解决方案更快:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
microbenchmark::microbenchmark(
dplyr = data %>% mutate_if(is.numeric, funs( case_when( . >= 1 ~ 1, TRUE ~ as.double(.)) ) ), datatable = data[, (num_cols):= lapply(.SD, function(x) { x[x>1] = 1 x}) ], base = {dataframe <- as.data.frame(data) dataframe[dataframe > 1] <- 1}, times = 100 ) # Unit: microseconds # expr min lq mean median uq max neval # dplyr 1782.384 1902.1210 2549.3977 1995.116 2099.9800 55628.570 100 # datatable 394.817 422.7605 466.5329 441.690 512.9020 628.282 100 # base 118.987 135.5120 160.1595 154.291 176.2255 300.469 100 |
- 很棒的方法!我认为警告来自一个非数字变量。排除此变量时,警告会消失。
- 再次警告,您应该使用 .SDcols=num_cols(参见 ?data.table)
你可以试试:
1
2 |
apply(data[, which(sapply(data, is.numeric))], 2,
function(x) {ifelse(x > 1, 1, x)}) |
它省略了 c 列,但之后您可以轻松地合并它。
来源:https://www.codenong.com/52832383/