#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 для другого программного обеспечения.