поворот к широкому фрейму данных с повторяющимися именами столбцов

#r #tidyverse #purrr

#r #tidyverse #муррр

Вопрос:

У меня есть фрейм данных, который мне нужно настроить в правильной конфигурации для внешней программы (PRISM Graphpad). В этом игрушечном примере у меня есть матрица условий 5×3 с повторяющимися измерениями для каждого условия. Первоначально для построения графиков и анализа в R данные представлены в надлежащем формате long tidy.

Хотя мне удобно поворачивать данные, я сталкиваюсь с проблемами, связанными с тем, что значения не являются уникальными при повороте DF в ширину. Мне нужно, чтобы копии были в соседних столбцах с одинаковыми именами, чтобы PRISM правильно распознавал вещи. Однако, когда я поворачиваю широко, повторяющиеся значения помещаются в список, потому что у них нет уникального идентификатора в id_cols.

В реальном примере матрица условий, конечно, намного больше, повторений больше (но одинаковое число для каждого условия), и, кроме того, каждый df является записью в столбце списка, поэтому мне, вероятно, потребуется применить решение с использованием purrr ::функция отображения.

 library(tidyverse)
df <- data.frame("ID" = c(rep(LETTERS[seq(1,5)], 2)),
              "cond1" = runif(10, 0, 1),
              "cond2" = runif(10, 1, 10),
              "cond3" = runif(10, 10, 100))


#// original long dataframe
long_df <- pivot_longer(data = df, cols = c("cond1", "cond2", "cond3"))
long_df
#> # A tibble: 30 x 3
#>    ID    name   value
#>    <chr> <chr>  <dbl>
#>  1 A     cond1  0.424
#>  2 A     cond2  9.01 
#>  3 A     cond3 61.6  
#>  4 B     cond1  0.460
#>  5 B     cond2  2.33 
#>  6 B     cond3 40.3  
#>  7 C     cond1  0.107
#>  8 C     cond2  5.82 
#>  9 C     cond3 23.9  
#> 10 D     cond1  0.714
#> # ... with 20 more rows


#// desired output
desired_df <- cbind(df[c(1:5),], df[c(6:10),])
desired_df <- desired_df[,c(1,2,6,3,7,4,8)]
colnames(desired_df)[c(3,5,7)] <- c("cond1", "cond2", "cond3")
desired_df
#>   ID     cond1     cond1    cond2    cond2    cond3    cond3
#> 1  A 0.4244798 0.8078372 9.005544 5.349371 61.61488 73.80651
#> 2  B 0.4596927 0.3509671 2.325029 8.636263 40.33949 66.54288
#> 3  C 0.1069974 0.3903294 5.817079 7.100623 23.87013 99.98683
#> 4  D 0.7144698 0.1005499 9.886948 7.006333 19.40680 66.86696
#> 5  E 0.2903691 0.6177356 8.890734 9.863695 46.56568 66.42537


#// result from pivot_wider
wide_df <- pivot_wider(long_df, id_cols = ID, names_from = name, values_from = value)
#> Warning: Values are not uniquely identified; output will contain list-cols.
#> * Use `values_fn = list` to suppress this warning.
#> * Use `values_fn = length` to identify where the duplicates arise
#> * Use `values_fn = {summary_fun}` to summarise duplicates
wide_df
#> # A tibble: 5 x 4
#>   ID    cond1     cond2     cond3    
#>   <chr> <list>    <list>    <list>   
#> 1 A     <dbl [2]> <dbl [2]> <dbl [2]>
#> 2 B     <dbl [2]> <dbl [2]> <dbl [2]>
#> 3 C     <dbl [2]> <dbl [2]> <dbl [2]>
#> 4 D     <dbl [2]> <dbl [2]> <dbl [2]>
#> 5 E     <dbl [2]> <dbl [2]> <dbl [2]>
 

Создано 2021-01-15 пакетом reprex (версия 0.3.0).0)

Комментарии:

1. Не рекомендуется дублировать имена столбцов

2. Понятно. Это не то, что я бы делал в R, но я считаю, что это обязательное условие для последующего программного обеспечения, чтобы правильно группировать повторы вместе. И спасибо за решение. Очевидно, что я должен просто сделать имена уникальными, сводными, а затем я могу просто изменить имена, если это необходимо. Спасибо!

Ответ №1:

Не рекомендуется иметь повторяющиеся имена столбцов, поэтому мы изменяем столбец «имя», добавляя уникальный индекс, созданный с rowid помощью , и используем его для изменения формы с помощью pivot_wider

 library(dplyr)
library(tidyr)
library(stringr)
library(data.table)
long_df %>% 
   mutate(name = str_c(name, "_", rowid(ID, name))) %>% 
   pivot_wider(names_from = name, values_from = value, names_sort = TRUE)
 

-выходной сигнал

 # A tibble: 5 x 7
#  ID    cond1_1 cond1_2 cond2_1 cond2_2 cond3_1 cond3_2
#  <chr>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
#1 A       0.293   0.920    6.44    9.14    18.5    71.9
#2 B       0.225   0.280    4.34    2.78    59.7    16.9
#3 C       0.704   0.764    7.05    1.40    75.3    64.0
#4 D       0.519   0.802    7.06    5.51    22.4    66.7
#5 E       0.663   0.255    3.88    2.25    30.1    14.2
 

Если у него должны быть повторяющиеся имена, просто уберите _\d в конце имени символ str_remove

Ответ №2:

Попробуйте это:

 library(tidyverse)
#Code
new <- df %>%
  pivot_longer(-1) %>%
  group_by(ID,name) %>%
  mutate(name=paste0(name,'.',row_number())) %>%
  pivot_wider(names_sort = T,names_from=name,values_from=value)
 

Вывод:

 # A tibble: 5 x 7
# Groups:   ID [5]
  ID    cond1.1 cond1.2 cond2.1 cond2.2 cond3.1 cond3.2
  <chr>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
1 A       0.619   0.851    4.49    9.17    70.9    84.2
2 B       0.989   0.542    9.64    3.57    55.3    28.3
3 C       0.594   0.602    5.16    8.97    26.2    19.0
4 D       0.349   0.244    5.29    8.52    44.8    17.7
5 E       0.683   0.848    7.27    8.07    97.3    73.9
 

Затем вы можете обработать следующим образом:

 #Further process
names(new) <- gsub("\..*","",names(new))
 

Вывод:

 # A tibble: 5 x 7
# Groups:   ID [5]
  ID    cond1 cond1 cond2 cond2 cond3 cond3
  <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 A     0.129 0.360  4.60  2.74  55.3  58.3
2 B     0.416 0.384  5.93  9.17  15.7  21.8
3 C     0.724 0.622  9.30  7.81  76.9  79.0
4 D     0.101 0.951  6.35  1.58  30.3  68.5
5 E     0.238 0.814  9.46  9.50  12.4  57.8
 

И экспортировать в .txt для другого программного обеспечения.