2014-02-13 3 views
0

У меня есть 3 data.table с будними днями в первом столбце и числовыми в остальной части столбца. В первых DT(DT1) он имеет 7 строк и n столбцов (n>2) числовых данных по каждому столбцу. Остальное DT (DT2, DT3) имеет 7 строк и 2 столбца с одним числовым столбцом.Как заменить элемент в data.table по условию (без цикла)?

Я хотел бы заменить элемент в каждом столбце (кроме столбца Weekdays), который меньше или равен элементу в DT2 элементом в DT3 с теми же будними днями.

x = c(8.38877450980392, 7.94021071115013, 7.95032679738562, 7.44576124567474, 
8.83645276292335) 
y = c(83.8877450980392, 79.4021071115013, 79.5032679738562, 74.4576124567474, 
88.3645276292335) 
DT1 = data.table(WeekDay = c("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"), a = abs(rnorm(7)*100), b = abs(rnorm(7)*100), c = abs(rnorm(7)*100), d = abs(rnorm(7)*100)) 
DT2 = data.table(WeekDay = c("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"), criteria = x) 
DT3 = data.table(WeekDay = c("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"), Replace_Value = y) 

Есть ли способ сделать это без петли? Используя только базу R, пожалуйста? Спасибо.

+0

A. Ваш пример не воспроизводится; x, y имеет 5 элементов, на вашей неделе - 7. B. Почему бы не объединить данные.tables – shadow

+0

Это моя позорная ошибка. Я намерен создать x, y с 7 элементами. Спасибо ^^. – Phongsakorn

ответ

0

Это следует сделать это:

setkey(DT1, WeekDay) 
setkey(DT2, WeekDay) 
mx.data <- as.matrix(DT1[, letters[1:4], with=F]) 
(DT1[DT2][DT3][, letters[1:4]:=as.data.table(ifelse(mx.data < criteria, Replace_Value, mx.data))]) 

Сначала я объединить все таблицы, как это было предложено Shadow. Затем, используя созданную мной матрицу с данными в DT1, я использую ifelse против criteria, который должен перерабатывать criteria для каждого столбца. Затем присваиваю результат ifelse, сначала преобразуя его в data.table в столбцы a-d с оператором замены :=.

Как указано тенью, мне пришлось изменить критерии, чтобы у них было правильное количество дней. Кроме того, мне пришлось сделать ваши критерии немного больше, поскольку они никогда не выполнялись (значения в DT1 всегда превышали crtieria). Вот что я сделал с вашими данными:

x = c(8.38877450980392, 7.94021071115013, 7.95032679738562, 7.44576124567474, 
     8.83645276292335, 50, 25) 
y = c(83.8877450980392, 79.4021071115013, 79.5032679738562, 74.4576124567474, 
     88.3645276292335, 50, 25) 
set.seed(1) 
DT1 = data.table(WeekDay = c("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"), a = abs(rnorm(7)*100), b = abs(rnorm(7)*100), c = abs(rnorm(7)*100), d = abs(rnorm(7)*100)) 
DT2 = data.table(WeekDay = c("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"), criteria = x * 7) 
DT3 = data.table(WeekDay = c("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"), Replace_Value = y) 
+0

О! для меня это новая техника. Это очень хорошо работает. Спасибо. – Phongsakorn

+0

@ user3305468, в зависимости от того, как это отвечает на ваш вопрос, пожалуйста, подумайте о том, чтобы отметить его как ответ. Благодарю. – BrodieG

Смежные вопросы