Автоматическое присвоение имени переменной с помощью mutate и for-loop - PullRequest
0 голосов
/ 05 октября 2018

У меня есть фрейм данных с 40 переменными G1_a, G1_b, ... до G20_a, G20_b (вытекает из опроса).Я хочу создать 20 новых переменных G1 ... G20, которые суммируют существующие переменные.

data <- data.frame(G1_a = c(0, 0, 0, 1, NA), 
               G1_b = c(0, 0, 1, 1, NA), 
               G2_a = c(0, 0, 0, 1, NA), 
               G2_b = c(0, 0, 1, 1, NA))

# Reshaping without for-loop:
data <- data %>% 
  mutate(G1 = case_when(
    G1_a == 1 ~ "own_offer", 
    G1_b == 1 ~ "no_offer", 
    T ~ NA_character_
  ))

data <- data %>% 
  mutate(G2 = case_when(
    G2_a == 1 ~ "own_offer", 
    G2_b == 1 ~ "no_offer", 
    T ~ NA_character_
  ))

Я хочу автоматизировать создание новых переменных в цикле for, что-то вроде:

# Reshaping with for-loop:
for(i in 1:2) {
 data <- data %>% 
   mutate(assign(paste0("G", i), case_when(
     get(paste0("G", i, "_a")) == 1 ~ "own_offer", 
     get(paste0("G", i, "_b")) == 1 ~ "no_offer", 
     T ~ NA_character_
    )))
  }

Мой вопрос состоит из двух частей:

1) Можно ли объединить assign с mutate?Мне известны такие подходы, как mutate(df, !!varname := Petal.width * n) (см. здесь ) для динамического назначения имен параметров.Однако я не смог объединить это с изменением формы данных, которые я хочу запустить.

2) Позволяет ли dplyr использовать paste0 вместе с case_when и mutate?

1 Ответ

0 голосов
/ 05 октября 2018

Это немного сложно, но я думаю, что это принципиальный способ сделать это.Конечный результат - фрейм данных с нужными столбцами, что позволяет избежать всех головных болей get() / assign() (и не загромождать рабочее пространство множеством производных переменных). Есть несколько шагов, гдемы меняем форму фрейма данных (широкий -> длинный -> частично широкий -> широкий), используя tidyr::gather() и tidyr::spread().Если это кажется ошеломляющим, поэкспериментируйте с остановкой последовательности каналов в различных промежуточных точках, чтобы увидеть, что было достигнуто до сих пор.

library(tidyr)
library(dplyr)
dds <- (dd
  %>% mutate(case=seq(n()))    ## need a variable to distinguish rows in original data set
  %>% gather(var,val,-case)    ## -> long format: {case, var={G1_a,G1_b,...}, val={0,1,NA}}
  %>% separate(var,c("var","response"))  ## split to "G1","G2" + "a", "b"
  %>% spread(response,val)               ## convert back to semi-wide: {case, var, a, b}
  ## now collapse rows to categorical value, as above
  %>% mutate(offer=case_when(a==1 ~ "own_offer",
                             b==1 ~ "no_offer",
                             TRUE ~ NA_character_))
  %>% select(-c(a,b))          ## clean up now-redundant variables
  %>% spread(var,offer)        ## convert back to wide format: {case, G1, G2, ...}
  %>% select(-case)            ## now redundant
)

Результат

         G1        G2
1      <NA>      <NA>
2      <NA>      <NA>
3  no_offer  no_offer
4 own_offer own_offer
5      <NA>      <NA>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...