Эффективно обрабатывать строки R-кадра без цикла в памяти - PullRequest
0 голосов
/ 27 июня 2018

Структура моего фрейма данных data1, содержащего более 1,5 миллионов строк, выглядит следующим образом:

data1 <- data.frame(NEW_UPC=c(11820005991,11820005991,11820005991,11820005991,11820005991,11820005991,11820005991,11820005991,11820005991,11820005991,11820005991,11820005991,11820005992,11820005992,11820005992,11820005992,11820005992,11820005992,11820005992,11820005992,11820005992,11820005993,11820005993,11820005993,11820005993,11820005993,11820005993,11820005993,11820005993,11820005993,11820005994,11820005994,11820005994,11820005994,11820005994,11820005994,11820005995,11820005995,11820005995,11820005995,11820005995,11820005995,11820005995,11820005995,11820005995),
                IRI_KEY=c(1073521,1073521,1073521,1073525,1073525,1073525,1078106,1078106,1078106,1078107,1078107,1078107,1073521,1073521,1073521,1073525,1073525,1073525,1078106,1078106,1078106,1073521,1073521,1073521,1073525,1073525,1073525,1078106,1078106,1078106,1073521,1073521,1073525,1073525,1078106,1078106,1073521,1073521,1073521,1073525,1073525,1073525,1078106,1078106,1078106),
                WEEK = c(1229,1230,1232,1218,1224,1229,1282,1285,1287,1229,1230,1232,1229,1230,1232,1218,1224,1229,1282,1285,1287,1229,1230,1232,1217,1221,1227,1270,1272,1273,1273,1274,1270,1272,1217,1221,1229,1230,1232,1218,1224,1229,1282,1285,1287),
                END=c(1232,1232,1232,1229,1229,1229,1287,1287,1287,1232,1232,1232,1232,1232,1232,1229,1229,1229,1287,1287,1287,1232,1232,1232,1227,1227,1227,1273,1273,1273,1274,1274,1272,1272,1221,1221,1232,1232,1232,1229,1229,1229,1287,1287,1287))

Мне нужно вставить столбец Exit.time, используя значения в столбцах WEEK и END и значение отсечения, равное 1287. Exit.time должно иметь значение 0 или 1 на основе следующей логики:

если WEEK = 1287, то Exit.time = 0.

если Week не равно 1287, но WEEK = END, тогда Exit.time = 1, в противном случае Exit.time = 0.

Для этого я попробовал следующее для цикла, и он делает то, что требуется в указанном выше наборе фиктивных данных.

i=0
for(i in 1:length(data2$NEW_UPC)){
  if (data2$WEEK[i]==1287) {
    data2$Exit.time[i] <- 0
  } else if(data2$WEEK[i]==data2$END[i]) {
    data2$Exit.time[i] <- 1
  } else {
    data2$Exit.time[i] <- 0
  }
}

Проблема в том, что когда я использую вышеуказанный цикл в моем реальном наборе данных, даже через час я не получаю вывод. Я полагаю, что циклы не эффективны, учитывая размер набора данных. Есть ли альтернативный способ сделать то, что я хочу? Я предпочитаю поддерживать порядок строк в data1, так как позже мне потребуется выполнить некоторые операции слияния.

Ответы [ 3 ]

0 голосов
/ 27 июня 2018

Существует несколько способов кодирования, в основном различающихся по семантике, они в основном делают одно и то же

База R:

data1$Exit.time <- (data1$WEEK != 1287 & data1$WEEK == data1$END)*1

Это включает в себя набор data1 много, поэтому есть короткий путь:

data1 <- within(data1, {
  Exit.time <- (WEEK != 1287 & WEEK == END)*1
})

Tidyverse: Tidyverse - это пакет пакетов, которые отлично подходят для манипулирования данными. Мы используем пакет dplyr, который является частью tidyverse, поэтому вы можете либо загрузить все это, либо просто dplyr:

library(tidyverse)
data1 <- data1 %>%
   mutate(
     Exit.time = (WEEK != 1287 & WEEK == END)*1
   )

(я преобразую из ИСТИНА / ЛОЖЬ в 0/1, умножив на 1. Меньше набирать)

0 голосов
/ 27 июня 2018

Использование data.table:

setDT(data1)[, Exit.time := ifelse(WEEK == 1287, 0, ifelse(WEEK != 1287 & WEEK == END, 1, 0))]
0 голосов
/ 27 июня 2018

Поскольку вам нужно Exit.time, чтобы быть 1, когда (WEEK == END) & WEEK != 1287 и 0 в противном случае, вы можете использовать as.numeric для результатов (WEEK == END) & WEEK != 1287, который меняет TRUE на 1 и FALSE на 0.

data1$Exit.time <- with(data1, as.numeric(WEEK != 1287 & WEEK == END))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...