Присвойте имя переменной как значение с помощью mutate_at и case_when - PullRequest
1 голос
/ 21 февраля 2020

У меня есть фрейм данных с некоторой информацией о значениях, хранящихся в некоторых именах переменных. В основном, если значение ячейки равно 0, ей следует присвоить NA; в противном случае я хотел бы присвоить имя переменной в качестве значения. Вероятно, лучше всего объяснить на этом примере:

library(tidyverse)

df <- tibble(observation = 0:5, var1 = as.character(0:5), var2 = as.character(1:6))

df
#> # A tibble: 6 x 3
#>   observation var1  var2 
#>         <int> <chr> <chr>
#> 1           0 0     1    
#> 2           1 1     2    
#> 3           2 2     3    
#> 4           3 3     4    
#> 5           4 4     5    
#> 6           5 5     6

df %>%
  mutate_at(vars(matches("var")),
            list(~case_when(. != "0" ~ "test")))
#> # A tibble: 6 x 3
#>   observation var1  var2 
#>         <int> <chr> <chr>
#> 1           0 <NA>  test 
#> 2           1 test  test 
#> 3           2 test  test 
#> 4           3 test  test 
#> 5           4 test  test 
#> 6           5 test  test

Создано в 2020-02-20 пакетом представитель (v0.3.0)

Я бы хотел, чтобы таблица выглядела следующим образом:

#> # A tibble: 6 x 3
#>   observation var1  var2 
#>         <int> <chr> <chr>
#> 1           0 <NA>  var2 
#> 2           1 var1  var2 
#> 3           2 var1  var2 
#> 4           3 var1  var2 
#> 5           4 var1  var2 
#> 6           5 var1  var2

Я не могу понять, что вставить в оператор case_when для доступа к имени переменной.

Спасибо!

Ответы [ 2 ]

2 голосов
/ 21 февраля 2020

Мы можем получить данные в длинном формате, заменить имя столбца где value = 0 на NA и снова получить данные в широком формате.

library(dplyr)
library(tidyr)

df %>%
  pivot_longer(cols = matches("var")) %>%
  mutate(value = replace(name, value == 0, NA)) %>%
  pivot_wider()

#  observation var1  var2 
#        <int> <chr> <chr>
#1           0 NA    var2 
#2           1 var1  var2 
#3           2 var1  var2 
#4           3 var1  var2 
#5           4 var1  var2 
#6           5 var1  var2 

В базе R мы можем сделать:

#get column name with "var" in it
cols  <- grep('var', names(df))
#get row/col index where value = 0
inds <- which(df[cols] == 0, arr.ind = TRUE)
#Replicate column names and assign
df[cols] <- rep(names(df[cols]), each = nrow(df))
#Replace 0 to NA 
df[cols][inds] <- NA
1 голос
/ 21 февраля 2020

Если мы добавим funs (устарело), ​​есть опция substitute

library(dplyr)
df %>% 
   mutate_at(vars(starts_with('var')), 
         funs(case_when(.!= 0  ~  deparse(substitute(.)))))
# A tibble: 6 x 3
#  observation var1  var2 
#        <int> <chr> <chr>
#1           0 <NA>  var2 
#2           1 var1  var2 
#3           2 var1  var2 
#4           3 var1  var2 
#5           4 var1  var2 
#6           5 var1  var2 

Или другой вариант imap

library(purrr)
df %>% 
   select(starts_with('var')) %>% 
   imap_dfc(~ case_when(. != 0 ~ .y)) %>% 
   bind_cols(df %>%
               select(-starts_with('var')), .)
# A tibble: 6 x 3
#  observation var1  var2 
#*       <int> <chr> <chr>
#1           0 <NA>  var2 
#2           1 var1  var2 
#3           2 var1  var2 
#4           3 var1  var2 
#5           4 var1  var2 
#6           5 var1  var2 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...