#r #dataframe #dplyr #pivot
Вопрос:
В настоящее время у меня есть набор данных протеомики с ~60 столбцами (пациенты и информация, такая как названия белков) и ~1800 строками (конкретные белки).
Мне нужно преобразовать формат из длинного в широкий, чтобы каждая строка соответствовала пациентам, а все столбцы представляли белки. Я могу выполнять (очень) простые преобразования, но в этом примере много столбцов, и, кроме того, требуется некоторое управление данными, поскольку необходимо создавать/извлекать новые ковариаты из исходных данных протеомики, приведенных ниже. Я просто не знаю, как действовать, и не нашел никаких решений, просматривая множество доступных пошаговых инструкций по преобразованию больших наборов данных, подобных этому.
Я предпочитаю dplyr
-входные данные, подсказки или решения.
Исходные данные протеомного программного обеспечения выглядят примерно так:
> head(Heat_BT)
# A tibble: 11 x 6
protein gene Intensity_10 Intensity_11 Intensity_MB_1 Intensity_Ref1
<chr> <chr> <chr> <chr> <chr> <chr>
1 NA NA Bruschi Bruschi Reichl Reichl
2 NA NA Ctrl Ctrl Tumor Ctrl
3 NA NA Hydro Hydro Malignant Hydro
4 NA NA Ctrl Ctrl MB Ctrl
5 von Willebrand factor VWF 0.674627721 0.255166769 0.970489979 0.215972215
6 Sex hormone-binding globulin SHBG 0.516914487 0.476843655 0.88173753 0.306484252
7 Glyceraldehyde-3-phosphate dehydrogenase GAPDH 0.622163594 0.231107563 0.71856463 0.204625234
8 Nestin NES 0.868476391 0.547319174 0.832109928 0.440162212
9 Heat shock 70 kDa protein 13 HSPA13 0.484973907 0.435322136 0.539334834 0.28678757
10 Isocitrate dehydrogenase [NADP], mitochondrial IDH2 1.017596364 0.107395157 0.710225344 0.251976997
11 Mannan-binding lectin serine protease 1 MASP1 0.491321206 0.434995681 0.812500775 0.403583705
Ожидаемый результат:
id lab malig diag VWF SHBG GAPDH NES HSPA13 IDH2 MASP1
1 Intensity_10 Bruschi Ctrl Hydro 0.6746277 0.5169145 0.6221636 0.8684764 0.4849739 1.0175964 0.4913212
2 Intensity_11 Bruschi Ctrl Hydro 0.2551668 0.4768437 0.2311076 0.5473192 0.4353221 0.1073952 0.4349957
3 Intensity_MB_1 Reichl Tumor Malignant 0.9704900 0.8817375 0.7185646 0.8321099 0.5393348 0.7102253 0.8125008
4 Intensity_Ref1 Reichl Ctrl Hydro 0.2159722 0.3064843 0.2046252 0.4401622 0.2867876 0.2519770 0.4035837
- Программное обеспечение proteomic автоматически выводит первые четыре строки в виде категорий, к которым относится каждый пациент.
На основе этих первых четырех строк:
- В широкий формат необходимо добавить четыре новые ковариаты: (1)
Heat_BT$id
соответствуют названию исследования каждого пациента, (2)Heat_BT$lab
соответствуют тому, в какой лаборатории были получены данные, (3)Heat_BT$malig
соответствуют ли случай пациента контрольному случаю или случаю опухоли и, наконец, (4)Heat_BT$diag
соответствуют основному диагнозу.
Данные
Heat_BT <- structure(list(protein = c(NA, NA, NA, NA, "von Willebrand factor",
"Sex hormone-binding globulin", "Glyceraldehyde-3-phosphate dehydrogenase",
"Nestin", "Heat shock 70 kDa protein 13", "Isocitrate dehydrogenase [NADP], mitochondrial",
"Mannan-binding lectin serine protease 1"), gene = c(NA, NA,
NA, NA, "VWF", "SHBG", "GAPDH", "NES", "HSPA13", "IDH2", "MASP1"
), Intensity_10 = c("Bruschi", "Ctrl", "Hydro", "Ctrl", "0.674627721",
"0.516914487", "0.622163594", "0.868476391", "0.484973907", "1.017596364",
"0.491321206"), Intensity_11 = c("Bruschi", "Ctrl", "Hydro",
"Ctrl", "0.255166769", "0.476843655", "0.231107563", "0.547319174",
"0.435322136", "0.107395157", "0.434995681"), Intensity_MB_1 = c("Reichl",
"Tumor", "Malignant", "MB", "0.970489979", "0.88173753", "0.71856463",
"0.832109928", "0.539334834", "0.710225344", "0.812500775"),
Intensity_Ref1 = c("Reichl", "Ctrl", "Hydro", "Ctrl", "0.215972215",
"0.306484252", "0.204625234", "0.440162212", "0.28678757",
"0.251976997", "0.403583705")), row.names = c(NA, -11L), class = c("tbl_df",
"tbl", "data.frame"))
Ответ №1:
Вот dplyr
решение для вас. Это два шага, так как сначала вам нужно будет собрать intensity
переменные.
Heat_BT <- Heat_BT %>% na.exclude()
Heat_BT[,-1] %>% pivot_longer(
cols = Intensity_10:Intensity_Ref1,
names_to = "id"
) %>% pivot_wider(
names_from = gene
) %>% mutate(
across(.cols = -"id", as.numeric)
)
Что дает следующее output
# A tibble: 4 x 8
id VWF SHBG GAPDH NES HSPA13 IDH2 MASP1
<chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 Intensity_10 0.674627721 0.516914487 0.622163594 0.868476391 0.484973907 1.017596364 0.491321206
2 Intensity_11 0.255166769 0.476843655 0.231107563 0.547319174 0.435322136 0.107395157 0.434995681
3 Intensity_MB_1 0.970489979 0.88173753 0.71856463 0.832109928 0.539334834 0.710225344 0.812500775
4 Intensity_Ref1 0.215972215 0.306484252 0.204625234 0.440162212 0.28678757 0.251976997 0.403583705
У меня возникли проблемы с видением связи между variables
тем , что вы хотели добавить из data
, поэтому я предположил, что, как только вы сможете pivot
правильно ввести свои данные, вы сможете заполнить остальные.
Я с радостью пересмотрю свой ответ, если вы сможете более ясно объяснить, как связаны эти переменные.
Лучшие
ПРАВКА: Обратите внимание, что я удалил первые четыре строки из data
, так как я не сразу увидел связь между переменными, которые вы хотели добавить.
ПРАВКА 2: Я предположил , что первые 3 строки являются ковариатами, которые вы хотите добавить, чтобы первая строка была lab
malig
и diag
соответственно.
# Extract the relevant information
# from the data.
id_cols <- bind_cols(
var = c("lab", "malig", "diag"),
Heat_BT[1:3,-c(1,2)]
) %>% group_by(var) %>% pivot_longer(
cols = Intensity_10:Intensity_Ref1, names_to = "id"
) %>% pivot_wider(
names_from = var,
)
# Remove these identifiers;
Heat_BT <- Heat_BT %>% na.exclude()
# Pivot the table;
pivoted_table <- Heat_BT[,-1] %>% pivot_longer(
cols = Intensity_10:Intensity_Ref1,names_to = "id"
) %>% pivot_wider(
names_from = gene,
) %>% mutate(
across(.cols = -"id", as.numeric)
)
# Join with the ID colums
left_join(
id_cols,
pivoted_table
)
Что дает output
,
# A tibble: 4 x 11
id lab malig diag VWF SHBG GAPDH NES HSPA13 IDH2 MASP1
<chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 Intensity_10 Bruschi Ctrl Hydro 0.674627721 0.516914487 0.622163594 0.868476391 0.484973907 1.017596364 0.491321206
2 Intensity_11 Bruschi Ctrl Hydro 0.255166769 0.476843655 0.231107563 0.547319174 0.435322136 0.107395157 0.434995681
3 Intensity_MB_1 Reichl Tumor Malignant 0.970489979 0.88173753 0.71856463 0.832109928 0.539334834 0.710225344 0.812500775
4 Intensity_Ref1 Reichl Ctrl Hydro 0.215972215 0.306484252 0.204625234 0.440162212 0.28678757 0.251976997 0.403583705
Это будет работать с имеющимися у вас данными, независимо от их размера. Очевидно, что вы можете сделать подход более пуленепробиваемым, заменив, например, cols = Intensity_10:Intensity_Ref1
на contains("intensity")
.
Правка 3
У вас намного больше переменных, чем указано здесь, поэтому, когда вы pivot
их не изменяете во время pivot
процесса.
Таким образом, мы можем использовать более надежный подход, предполагая, что все variables
не представленные здесь данные аналогичны приведенным, соответствующим образом изменив cols
аргумент.
# Extract the relevant information
# from the data.
id_cols <- bind_cols(
var = c("lab", "malig", "diag"),
Heat_BT[1:3,-c(1,2)]
) %>% group_by(var) %>% pivot_longer(
cols = -"var", names_to = "id"
) %>% pivot_wider(
names_from = var,
)
# Remove these identifiers;
Heat_BT <- Heat_BT[-(1:4),]
# Pivot the table;
pivoted_table <- Heat_BT[,-1] %>% pivot_longer(
cols = -"gene",
names_to = "id"
) %>% pivot_wider(
names_from = gene,
) %>% mutate(
across(.cols = -"id", as.numeric)
)
# Join with the ID colums
left_join(
id_cols,
pivoted_table
)
Что дает тот же результат, что и выше.
Комментарии:
1. Привет @Serkan, большое вам спасибо за это решение. Все значения в выходных данных EDIT 2
as.character
следующие . Есть ли простой способ убедиться, что все значения в выходных данных являютсяas.numeric
?2. Вы можете добавить
values_fn = as.numeric
pivot_wider
, но лично я бы сделал этоmutate
после того, как у вас будет желаемый результат!3. Интересный. Отображается ли эта ошибка в ваших собственных данных или она также отображается в предоставленных вами образцах данных? Вы можете это проверить, пожалуйста?
4. Я изменю свой ответ, и если это не сработает, мы сможем рассмотреть альтернативные решения. Все остальные переменные аналогичны тем, которые вы указали здесь, да? Все они должны быть
numeric
переменными, да?5. Хорошо, я изменил свой ответ. Дай мне знать, как все прошло. Помните , что решение предполагает, что первые четыре строки не нужны для чего-либо, кроме создания
lab
,malig
иdiag
.
Ответ №2:
Вы могли бы сделать:
Heat_BT[,2][1:3] <- c('lab', 'malig', 'diag')
data.table::transpose(Heat_BT[,-1],keep.names = 'gene',make.names = TRUE)
gene lab malig diag NA VWF SHBG GAPDH NES HSPA13 IDH2 MASP1
1 Intensity_10 Bruschi Ctrl Hydro Ctrl 0.674627721 0.516914487 0.622163594 0.868476391 0.484973907 1.017596364 0.491321206
2 Intensity_11 Bruschi Ctrl Hydro Ctrl 0.255166769 0.476843655 0.231107563 0.547319174 0.435322136 0.107395157 0.434995681
3 Intensity_MB_1 Reichl Tumor Malignant MB 0.970489979 0.88173753 0.71856463 0.832109928 0.539334834 0.710225344 0.812500775
4 Intensity_Ref1 Reichl Ctrl Hydro Ctrl 0.215972215 0.306484252 0.204625234 0.440162212 0.28678757 0.251976997 0.403583705
Комментарии:
1. Привет @Onyambu, большое вам спасибо за ваш вклад. Я получаю сообщение об ошибке при попытке запустить ваш скрипт:
> Heat_BT[,2][1:3] <- c('lab', 'malig', 'diag')
выдает следующее: Ошибка: Назначенные данные `c(«лаборатория», «малиг», «diag») должны быть совместимы с существующими данными. x Существующие данные содержат 1811 строк. x Назначенные данные содержат 3 строки. ℹ Перерабатываются только векторы размера 1. Знаете ли вы, как это можно исправить?