условное изменение значений столбцов с использованием `dplyr`

#r #dplyr

#r #dplyr

Вопрос:

Я использую WRS2 для выполнения надежных попарных сравнений. Но одна проблема заключается в том, что он удаляет имена групповых уровней из выходных фреймов данных и сохраняет их в другом объекте.

 # setup
set.seed(123)
library(WRS2)
library(tidyverse)

# robust pairwise comparisons
x <- lincon(libido ~ dose, data = viagra, tr = 0.1)

# comparisons
x$comp
#>      Group Group psihat  ci.lower    ci.upper    p.value
#> [1,]     1     2   -1.0 -3.440879  1.44087853 0.25984505
#> [2,]     1     3   -2.8 -5.536161 -0.06383861 0.04914871
#> [3,]     2     3   -1.8 -4.536161  0.93616139 0.17288911

# vector with group level names
x$fnames
#> [1] "placebo" "low"     "high"
  

Я могу преобразовать его в tibble :

 # converting to tibble
suppressMessages(as_tibble(x$comp, .name_repair = "unique")) %>%
  dplyr::rename(group1 = Group...1, group2 = Group...2) 
#> # A tibble: 3 x 6
#>   group1 group2 psihat ci.lower ci.upper p.value
#>    <dbl>  <dbl>  <dbl>    <dbl>    <dbl>   <dbl>
#> 1      1      2   -1      -3.44   1.44    0.260 
#> 2      1      3   -2.8    -5.54  -0.0638  0.0491
#> 3      2      3   -1.8    -4.54   0.936   0.173
  

Затем я хотел бы заменить group числовые значения столбцов фактическими именами, включенными в fnames (so map fnames [1] -> 1, fnames [2] -> 2, и так далее).

Таким образом, конечный фрейм данных должен выглядеть примерно следующим образом-

 #> # A tibble: 3 x 6
#>   group1 group2 psihat ci.lower ci.upper p.value
#>    <dbl>  <dbl>  <dbl>    <dbl>    <dbl>   <dbl>
#> 1      placebo      low   -1      -3.44   1.44    0.260 
#> 2      placebo      high   -2.8    -5.54  -0.0638  0.0491
#> 3      low      high   -1.8    -4.54   0.936   0.173
  

В этом случае было легко просто скопировать и вставить три значения, но я хочу иметь обобщаемый подход, при котором он работает независимо от количества уровней. Как я могу это сделать с помощью dplyr ?

Ответ №1:

Использование именованного вектора для сопоставления tidyverse . Это соответствует значению, а не последовательности индекса, т.Е. Если значение в столбцах ‘Group’ не находится в последовательности или символе, это все равно будет работать

 library(dplyr)
as_tibble(x$comp, .name_repair = 'unique') %>%
   mutate(across(starts_with("Group"), 
         ~ setNames(x$fnames, seq_along(x$fnames))[as.character(.)]))
  

Ответ №2:

Удовлетворяет ли это ваши потребности :

 names <- c("A","B","C")

df = data.frame(group=c(1,2,3))
library(dplyr)
df %>% mutate(group = names[group])

  group
1     A
2     B
3     C
  

Ответ №3:

Вот подход, использующий recode функцию, с вектором перекодирования, созданным программно из данных:

 # Setup
set.seed(123)
library(WRS2)
library(tidyverse)

x <- lincon(libido ~ dose, data = viagra, tr = 0.1)

# Create recoding vector
recode.vec = x$fnames %>% set_names(1:length(x$fnames))

# Recode columns
x.comp = x$comp %>% 
  as_tibble(.name_repair=make.unique) %>% 
  mutate(across(starts_with("Group"), ~recode(., !!!recode.vec)))
  

Вывод:

 x.comp

#> # A tibble: 3 x 6
#>   Group   Group.1 psihat ci.lower ci.upper p.value
#>   <chr>   <chr>    <dbl>    <dbl>    <dbl>   <dbl>
#> 1 placebo low       -1      -3.44   1.44    0.260 
#> 2 placebo high      -2.8    -5.54  -0.0638  0.0491
#> 3 low     high      -1.8    -4.54   0.936   0.173
  

Ответ №4:

Попробуйте использовать этот tidyverse подход для форматирования данных в течение длительного времени после извлечения объектов в виде tibbles. Вы можете использовать left_join() для получения своих групп по своему усмотрению. Вот код, позволяющий получить что-то близкое к тому, что вы хотите:

 # setup
set.seed(123)
library(WRS2)
library(tidyverse)
# robust pairwise comparisons
x <- lincon(libido ~ dose, data = viagra, tr = 0.1)
#Transform to tibble
df1 <- suppressMessages(as_tibble(x$comp, .name_repair = "unique")) %>%
  dplyr::rename(group1 = Group...1, group2 = Group...2) 
#Extract labels
df2 <- tibble(treat=x$fnames) %>% mutate(value=1:n())
#Format to long df1
df1 <- df1 %>% 
  mutate(id=1:n()) %>%
  pivot_longer(cols = c(group1,group2)) %>%
  rename(group=name) %>% left_join(df2) %>% select(-value) %>%
  pivot_wider(names_from = group,values_from=treat) %>% select(-id)
  

Вывод:

 # A tibble: 3 x 6
  psihat ci.lower ci.upper p.value group1  group2
   <dbl>    <dbl>    <dbl>   <dbl> <chr>   <chr> 
1   -1      -3.44   1.44    0.260  placebo low   
2   -2.8    -5.54  -0.0638  0.0491 placebo high  
3   -1.8    -4.54   0.936   0.173  low     high