R data.table зацикливание на столбцах для условной замены значений строк - PullRequest
0 голосов
/ 03 мая 2018

В поисках того, что должно быть невероятно простым решением. Я хотел бы условно заменить значение в строке, если оно удовлетворяет заданному условию (меньше нуля), и я хотел бы сделать это для сотен (двадцать в примере) столбцов, каждый из которых содержит 150 миллионов строк. Я на седьмом часу пробую каждое решение, найденное в стеке, поэтому, пожалуйста, не помечайте это как дубликат. :-)

Данные:

library(data.table)
library(dplyr)
dt <- data.table(id=c(1:1000), x=rnorm(1:1000,60,20))

Использование интуитивного цикла для создания новых столбцов:

## Create new variables
for(i in 50:70) {
  dt[, paste0("y", i) := i-x]
}

Простая команда для одного столбца, прекрасно работает:

dt$y60[dt$y60<0 ] <- 0

Поместите это внутрь цикла, и оно не будет работать:

for(i in 50:70) {
  dt$y[i][dt$y[i]<0] <- 0
}

Каким должен быть простой подход DT, не повезло:

for(i in 50:70) {
  dt[y[i]<0, y[i] := 0]
}

Попытка подхода ifelse(), не повезло:

for(i in 50:70) {
  dt$y[i] <- ifelse(dt$y[i] < 0, 0, dt$y[i])
}

Попытка сначала создать список, а затем использовать set(), без кубиков:

list <- dt %>% dplyr:: select(starts_with("y"))
for(i in 50:70) {
  set(dt, i, list , 0)
}

Моя жизнь в твоих руках, спасибо !!

Ответы [ 2 ]

0 голосов
/ 03 мая 2018

Если вам нужно изменить значение столбцов, начиная с, скажем, y, то решением может быть использование mutate_at для проверки только выбранных столбцов:

library(dplyr)
dt %>% mutate_at(vars(starts_with("y")), funs(ifelse(.<0,0,.)))

Если вы хотите выполнить проверку для всех столбцов, то подстрочной строки должно быть достаточно:

dt[dt<0] <- 0
0 голосов
/ 03 мая 2018

Вариант 1 с использованием :=:

dt[, (paste0("y", 50:70)) := lapply(.SD, function(x) {x[x<0] <- 0; x}), .SDcols=paste0("y", 50:70)]

Вариант 2 с использованием set:

for (j in paste0("y", 50:70)) {
    set(dt, dt[,which(get(j) < 0)], j, 0)
}

данные:

library(data.table)
dt <- data.table(id=c(1:1000), x=rnorm(1:1000,60,20))
for(i in 50:70) {
    dt[, paste0("y", i) := i-x]
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...