Создать новую переменную с другими переменными на основе другой переменной - PullRequest
0 голосов
/ 28 мая 2019

У меня 4 переменные даты и 1 группирующая переменная.На основании значения в переменной группировки необходимо ввести дату в новую переменную.Мои данные выглядят так: (https://www.dropbox.com/s/wlfv89qc1jzwfgk/vb.JPG)

Я хочу создать новую переменную, основанную на значении группы. Когда для группы AI требуется дата1, для группы BI требуется дата2 и т. Д.

Это код, который я использовал:

if (tabel$group == A) {
  newvar <- tabel$date1
} else if (tabel$group == B) {
  newvar <- tabel$date2
} else if (tabel$group == C) {
  newvar <- tabel$date3
} else if (tabel$group == D) {
  newvar <- tabel$date4
}

Этот код выдает мне предупреждение:

(In if (tabel $ group == 1) {:условие имеет длину> 1, и будет использоваться только первый элемент

Ответы [ 2 ]

0 голосов
/ 29 мая 2019

Я уверен, что раньше об этом спрашивали и отвечали несколько раз, но я не нашел хорошего дубликата.

Вложенный ifelse() не всегда является лучшим решением.Трудно кодировать, читать и поддерживать с большим количеством скобок.Кроме того, ifelse() может неожиданно изменить тип результата, например, класс Date.

Итак, я хочу опубликовать некоторые альтернативы

Подмножество с использованием match()

В этом примере используется тот факт, что первая буква «А» соответствует первому столбцу даты date1 и т. Д. Таким образом, в общем случае это может быть неприменимо:

indices <- matrix(c(seq.int(nrow(tabel)), match(tabel$group, LETTERS[1:4])), ncol = 2)
newvar <- tabel[, -1][indices]
newvar
 [1] "2011-01-01" "2011-01-02" "2011-01-03" "2012-02-04" "2012-02-05" "2012-02-06" "2013-03-07" "2013-03-08" "2013-03-09"
[10] "2014-04-10" "2014-04-11" "2014-04-12"

indices (номер строки, номер столбца), которые используются для поднабора:

      [,1] [,2]
 [1,]    1    1
 [2,]    2    1
 [3,]    3    1
 [4,]    4    2
 [5,]    5    2
 [6,]    6    2
 [7,]    7    3
 [8,]    8    3
 [9,]    9    3
[10,]   10    4
[11,]   11    4
[12,]   12    4

tabel[, -1] пропускает первый столбец (group).

case_when()

Это версия нескольких операторов if_else() из пакета dplyr.

newvar <- dplyr::case_when(
  tabel$group == "A" ~ tabel$date1,
  tabel$group == "B" ~ tabel$date2,
  tabel$group == "C" ~ tabel$date3,
  tabel$group == "D" ~ tabel$date4)

или

library(dplyr)
newvar <- tabel %>% 
  transmute(value = case_when(group == "A" ~ date1,
                              group == "B" ~ date2,
                              group == "C" ~ date3,
                              group == "D" ~ date4)) %>% 
  pull(value)

Соединение с справочной таблицей с использованием data.table

Справочные таблицы обрабатывают отношение между group и именем столбца как данные и, следовательно, их легко создавать и поддерживать.С другой стороны, tabel необходимо преобразовать из широкого в длинный формат, прежде чем его можно объединить с lookup:

library(data.table)
lookup <- data.table(group = LETTERS[1:4], variable = paste0("date", 1:4))
newvar <- melt(setDT(tabel), id.vars = "group")[lookup, on = .(group, variable)]$value

lookup
   group variable
1:     A    date1
2:     B    date2
3:     C    date3
4:     D    date4

Измененный длинный формат

melt(setDT(tabel), id.vars = "group")
    group variable      value
 1:     A    date1 2011-01-01
 2:     A    date1 2011-01-02
 3:     A    date1 2011-01-03
 4:     B    date1 2011-01-04
 5:     B    date1 2011-01-05
 6:     B    date1 2011-01-06
 7:     C    date1 2011-01-07
 8:     C    date1 2011-01-08
 9:     C    date1 2011-01-09
10:     D    date1 2011-01-10
11:     D    date1 2011-01-11
12:     D    date1 2011-01-12
13:     A    date2 2012-02-01
14:     A    date2 2012-02-02
15:     A    date2 2012-02-03
16:     B    date2 2012-02-04
17:     B    date2 2012-02-05
18:     B    date2 2012-02-06
19:     C    date2 2012-02-07
20:     C    date2 2012-02-08
21:     C    date2 2012-02-09
22:     D    date2 2012-02-10
23:     D    date2 2012-02-11
24:     D    date2 2012-02-12
25:     A    date3 2013-03-01
26:     A    date3 2013-03-02
27:     A    date3 2013-03-03
28:     B    date3 2013-03-04
29:     B    date3 2013-03-05
30:     B    date3 2013-03-06
31:     C    date3 2013-03-07
32:     C    date3 2013-03-08
33:     C    date3 2013-03-09
34:     D    date3 2013-03-10
35:     D    date3 2013-03-11
36:     D    date3 2013-03-12
37:     A    date4 2014-04-01
38:     A    date4 2014-04-02
39:     A    date4 2014-04-03
40:     B    date4 2014-04-04
41:     B    date4 2014-04-05
42:     B    date4 2014-04-06
43:     C    date4 2014-04-07
44:     C    date4 2014-04-08
45:     C    date4 2014-04-09
46:     D    date4 2014-04-10
47:     D    date4 2014-04-11
48:     D    date4 2014-04-12
    group variable      value

Соединение с справочной таблицей с использованием dplyr и tidyr

library(dplyr)
library(tidyr)
lookup <- tibble(group = LETTERS[1:4], key = paste0("date", 1:4))
newvar <- tabel %>% 
  gather(key, value, -group) %>% 
  inner_join(lookup) %>% 
  pull(value)

Это работает, как указано выше: создать видвверх таблицы, изменить форму с широкого на длинный формат и присоединиться.pull() возвращает простой вектор результата.

Воспроизводимые данные

tabel <- data.frame(group = rep(LETTERS[1:4], each = 3L),
                    date1 = as.Date("2011-01-01") + 0:11,
                    date2 = as.Date("2012-02-01") + 0:11,
                    date3 = as.Date("2013-03-01") + 0:11,
                    date4 = as.Date("2014-04-01") + 0:11)
tabel
    group      date1      date2      date3      date4
 1:     A 2011-01-01 2012-02-01 2013-03-01 2014-04-01
 2:     A 2011-01-02 2012-02-02 2013-03-02 2014-04-02
 3:     A 2011-01-03 2012-02-03 2013-03-03 2014-04-03
 4:     B 2011-01-04 2012-02-04 2013-03-04 2014-04-04
 5:     B 2011-01-05 2012-02-05 2013-03-05 2014-04-05
 6:     B 2011-01-06 2012-02-06 2013-03-06 2014-04-06
 7:     C 2011-01-07 2012-02-07 2013-03-07 2014-04-07
 8:     C 2011-01-08 2012-02-08 2013-03-08 2014-04-08
 9:     C 2011-01-09 2012-02-09 2013-03-09 2014-04-09
10:     D 2011-01-10 2012-02-10 2013-03-10 2014-04-10
11:     D 2011-01-11 2012-02-11 2013-03-11 2014-04-11
12:     D 2011-01-12 2012-02-12 2013-03-12 2014-04-12
0 голосов
/ 28 мая 2019

Вам нужно выполнить это по строкам ... один из вариантов - использовать вложенные ifelse()

newvar=ifelse(tabel$group=='A',tabel$date1,
              ifelse(tabel$group=='B',tabel$date2,
                     ifelse(tabel$group=='C',tabel$date3,tabel$date4))))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...