dplyr / purrr перебирает столбцы и строки - PullRequest
1 голос
/ 27 марта 2020

Я пытаюсь сбросить (установить в NA) значения в 1 столбце, основываясь на значениях в другом столбце; и сделать это через большой набор столбцов. Идея состоит в том, чтобы затем передать данные в функцию построения графиков, чтобы сгенерировать разные графики для разных срезов данных.

Вот воспроизводимый пример:

d <- data.frame("A_agree" = sample(1:7, 20, replace=T),
                "B_agree" = sample(1:7, 20, replace=T),
                "C_agree" = sample(1:7, 20, replace=T),
                "A_change" = sample(1:5, 20, replace=T),
                "B_change" = sample(1:5, 20, replace=T),
                "C_change" = sample(1:5, 20, replace=T))

Я уже нашел Следующее решение с использованием базы R, но это, конечно, медленно, и я пытаюсь учиться все больше и больше dplyr, поэтому мне было интересно, как этого добиться в dplyr

d.positive <- d
for (n in (c("A","B","C"))) {
  for (i in 1:nrow(d.positive)) {
    d.positive[i, paste0(n, "_agree")] <- ifelse(d.positive[i, paste0(n, "_change")] > 3,
                                                 d.positive[i, paste0(n, "_agree")],
                                                 NA)
  }
}
d.neutral <- d
for (n in (c("A","B","C"))) {
  for (i in 1:nrow(d.neutral)) {
    d.neutral[i, paste0(n, "_agree")] <- ifelse(d.neutral[i, paste0(n, "_change")] == 3,
                                                 d.neutral[i, paste0(n, "_agree")],
                                                 NA)
  }
}
d.negative <- d
for (n in (c("A","B","C"))) {
  for (i in 1:nrow(d.negative)) {
    d.negative[i, paste0(n, "_agree")] <- ifelse(d.negative[i, paste0(n, "_change")] < 3,
                                                 d.negative[i, paste0(n, "_agree")],
                                                 NA)
  }
}

Я думал, что используйте gather(), а затем проверьте для каждой строки, больше ли соответствующий столбец (следовательно, !!dimension), чем определенное значение (в данном случае 3), но, похоже, оно не работает?

d %>%
  gather(dimension,
         value,
         paste0(c("A","B","C"), "_agree")
         ) %>%
  case_when(!!dimension > 3 ~ value=NA)

В качестве альтернативы я думал, что буду использовать map2_dfr из purrr, но я не думаю, что он перебирает ячейки, просто берет весь столбец, следовательно, это не работает:

map2_dfr(.x = d %>%
                 select( paste0(c("A","B","C"), "_agree") ),
         .y = d %>%
                 select( paste0(c("A","B","C"), "_change") ),
         ~ if_else(.y > 3, x, NA)} )

Любые указатели были бы действительно полезны, чтобы продолжать узнавать о чудесном мире dplyr!

Ответы [ 2 ]

2 голосов
/ 27 марта 2020

Я понимаю, что вы хотите узнать о purrr, но база R здесь проще:

d.positive <- d  

check  <- d.positive[4:6] <= 3 #it's the same condition
d.positive[,1:3][check] <- NA

> d.positive
   A_agree B_agree C_agree A_change B_change C_change
1        1      NA      NA        4        3        2
2        2       2      NA        4        5        2
3        4      NA      NA        4        3        1
4        1      NA      NA        4        1        2
5       NA       1      NA        2        4        1
6       NA       7      NA        3        5        1
7       NA       6      NA        1        5        1
8       NA       6       4        2        5        5
9        4      NA      NA        4        1        2
10       1      NA      NA        5        1        2
11      NA      NA      NA        3        1        2
12      NA      NA      NA        1        3        3
13      NA      NA      NA        1        1        1
14      NA      NA      NA        3        2        3
15       1      NA      NA        5        3        3
16       2      NA      NA        4        3        2
17      NA      NA       6        1        1        4
18      NA      NA      NA        1        1        2
19      NA      NA      NA        2        3        1
20      NA      NA      NA        1        3        1

1 голос
/ 27 марта 2020

Я бы предложил использовать пакет tidyr в сочетании с dplyr. В нем есть новые функции pivot_longer и pivot_wider, которые заменяют старые gather и spread.

. Использование комбинации обоих решений может быть следующим:

d.neutral1 = 
  d %>% 
  mutate(row = row_number() ) %>% 
  pivot_longer(-row, names_sep = "_", names_to = c("name","type") ) %>% 
  pivot_wider(names_from = type, values_from = value) %>% 
  mutate(result = if_else(change == 3, agree, NA_integer_))

и если вы хотите подобную форму к оригиналу

d.neutral1 %>% 
  select(-agree, -change) %>% 
  pivot_wider(names_from = name, values_from = result)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...