Я хочу написать цикл for (или аналогичный), в котором, если df.1a, df.2a, df.3a соответствует subtypes$clust, я хочу подмножить фрейм данных exp.df.
df.1a <- exp.df[colnames(exp.df) %in% rownames(subtypes),] && subtypes[subtypes$clust= = "1a",]
df.2a <- exp.df[colnames(exp.df) %in% rownames(subtypes),] && subtypes[subtypes$clust= = "2a",]
df.1b <- exp.df[colnames(exp.df) %in% rownames(subtypes),] && subtypes[subtypes$clust= = "1b",]
df.2b <- exp.df[colnames(exp.df) %in% rownames(subtypes),] && subtypes[subtypes$clust= = "2b",]
Выслеживать:
Error in exp[colnames(exp.df) %in% rownames(subtypes), ] && subtypes[subtypes$clust == :
invalid 'x' type in 'x && y'
Данные:
Exp.df
> dput(exp.df[1:5,1:5])
structure(list(TCGA.2K.A9WE.01A = c(7.65342121905285, 6.35598354101006,
14.3511850042327, 10.3737643425674, 10.0819596419255), TCGA.2Z.A9J1.01A = c(5.09389393824392,
6.93597002271109, 12.4136523086721, 11.1918237390263, 10.1912122382252
), TCGA.2Z.A9J3.01A = c(4.70168212029528, 7.54694769203808, 10.1689338100564,
9.96839262629172, 9.87305770150294), TCGA.2Z.A9J5.01A = c(7.99645936536463,
6.89258167250936, 13.6832285748428, 10.3714563849361, 10.4176870383992
), TCGA.2Z.A9J6.01A = c(5.13719199914349, 6.92859654071157, 12.0367193976262,
10.8202555636581, 10.3262700402849)), row.names = c("A1BG", "A2LD1",
"A2M", "A4GALT", "AAAS"), class = "data.frame")
Subtypes
> dput(subtypes[1:5,])
structure(list(clust = c("1a", "2a", "2b", "1b", "2a", row.names = c("TCGA.2K.A9WE.01A",
"TCGA.2Z.A9J1.01A", "TCGA.2Z.A9J3.01A", "TCGA.2Z.A9J5.01A", "TCGA.2Z.A9J6.01A", class = "data.frame")
Ожидаемый результат:
Df.1a
structure(list(TCGA.2K.A9WE.01A = c(7.65342121905285, 6.35598354101006,
14.3511850042327, 10.3737643425674, 10.0819596419255), TCGA.2Z.A9J1.01A = c(5.09389393824392,
6.93597002271109, 12.4136523086721, 11.1918237390263, 10.1912122382252
)), row.names = c("A1BG", "A2LD1",
"A2M", "A4GALT", "AAAS"), class = "data.frame")
Df.2a
structure(list(TCGA.2Z.A9J3.01A = c(4.70168212029528, 7.54694769203808, 10.1689338100564,
9.96839262629172, 9.87305770150294), TCGA.2Z.A9J6.01A = c(5.13719199914349, 6.92859654071157, 12.0367193976262,
10.8202555636581, 10.3262700402849)), row.names = c("A1BG", "A2LD1",
"A2M", "A4GALT", "AAAS"), class = "data.frame")
Df.1b
structure(TCGA.2Z.A9J5.01A = c(7.99645936536463,
6.89258167250936, 13.6832285748428, 10.3714563849361, 10.4176870383992
), row.names = c("A1BG", "A2LD1",
"A2M", "A4GALT", "AAAS"), class = "data.frame")
Df.2b
structure(TCGA.2Z.A9J3.01A = c(4.70168212029528, 7.54694769203808, 10.1689338100564,
9.96839262629172, 9.87305770150294)), row.names = c("A1BG", "A2LD1",
"A2M", "A4GALT", "AAAS"), class = "data.frame")
exp.df[colnames(exp.df) %in% rownames(subtypes),] && subtypes[subtypes$clust= = "1a",]
Похоже, вы пытаетесь создать подмножество столбцов exp.df, где они соответствуют именам строк subtypes data.frame, где clust= = "1a". Вы можете написать эту операцию подмножества следующим образом:
exp.df[,
colnames(exp.df) %in% rownames(subtypes[subtypes$clust= = "1a",,drop=FALSE]),
drop=FALSE]
Обратите внимание на drop=FALSE. Без этого, поскольку data.frame представляет собой только один столбец, R упрощает его до вектора, и вы теряете имена строк. Вместо этого вы можете подмножить все rownames в список и выполнить итерацию по этому списку с помощью lapply():
# Create a list of groups
col_groups <- split(rownames(subtypes), subtypes$clust)
df_list <- lapply(
col_groups,
\(grp)
exp.df[, names(exp.df) %in% grp, drop = FALSE]
)
Преимущество этого заключается в сохранении всех результирующих фреймов данных в списке, который легко повторять и подмножать.
names(df_list)
# "1a" "1b" "2a" "2b"
# subsetting
df_list[["2a"]]
# TCGA.2Z.A9J1.01A TCGA.2Z.A9J6.01A
# <num> <num>
# 1: 5.093894 5.137192
# 2: 6.935970 6.928597
# 3: 12.413652 12.036719
# 4: 11.191824 10.820256
# 5: 10.191212 10.326270
Если вам нужно вернуть элементы в глобальную среду (что, как правило, не очень хорошая идея, если у вас много фреймов данных в списке), вы можете сделать:
# Make sure names don't start with numbers, e.g. `1a`, `2a`
names(df_list) <- paste0("exp.", names(df_list))
list2env(df_list, envir = globalenv())
exp.2a
# TCGA.2Z.A9J1.01A TCGA.2Z.A9J6.01A
# <num> <num>
# 1: 5.093894 5.137192
# 2: 6.935970 6.928597
# 3: 12.413652 12.036719
# 4: 11.191824 10.820256
# 5: 10.191212 10.326270
Я не люблю думать о drop = FALSE. Вместо этого я бы использовал для этого пакет data.table:
# Load package and make each data.frame into a data.table
library(data.table)
setDT(subtypes, keep.rownames = TRUE)
setDT(exp.df)
col_groups <- split(subtypes$rn, subtypes$clust)
df_list <- lapply(col_groups,
\(grp)
exp.df[, ..grp]
)
Вот еще один подход, в котором мы перебираем subtypes data.frame по группам, соответствующим образом выбираем столбцы и записываем эти data.frame в глобальную среду:
library(dplyr)
library(rlang)
# convert rownames to columns
exp.df2 <- tibble::rownames_to_column(exp.df, "type")
subtypes2 <- tibble::rownames_to_column(subtypes, "col")
subtypes2 %>%
group_by(clust) %>%
group_walk(~ semi_join(.x, tibble(col = colnames(exp.df2))) %>%
{select(exp.df2, all_of(.$col))} %>%
{env_bind(globalenv(), !! sym(paste0("df.", .y$clust)) := .)}
)
# example data.frame
df.1a
#> TCGA.2K.A9WE.01A
#> 1 7.653421
#> 2 6.355984
#> 3 14.351185
#> 4 10.373764
#> 5 10.081960
Данные из ОП
exp.df <- structure(list(TCGA.2K.A9WE.01A = c(7.65342121905285, 6.35598354101006,
14.3511850042327, 10.3737643425674, 10.0819596419255), TCGA.2Z.A9J1.01A = c(5.09389393824392,
6.93597002271109, 12.4136523086721, 11.1918237390263, 10.1912122382252
), TCGA.2Z.A9J3.01A = c(4.70168212029528, 7.54694769203808, 10.1689338100564,
9.96839262629172, 9.87305770150294), TCGA.2Z.A9J5.01A = c(7.99645936536463,
6.89258167250936, 13.6832285748428, 10.3714563849361, 10.4176870383992
), TCGA.2Z.A9J6.01A = c(5.13719199914349, 6.92859654071157, 12.0367193976262,
10.8202555636581, 10.3262700402849)), row.names = c("A1BG", "A2LD1",
"A2M", "A4GALT", "AAAS"), class = "data.frame")
subtypes <- structure(list(clust = c("1a", "2a", "2b", "1b", "2a")),
row.names = c("TCGA.2K.A9WE.01A", "TCGA.2Z.A9J1.01A", "TCGA.2Z.A9J3.01A", "TCGA.2Z.A9J5.01A", "TCGA.2Z.A9J6.01A"),
class = "data.frame")
Created on 2023-02-15 by the reprex package (v2.0.1)
@SamR Я добавил ожидаемый результат и изменил имя exp().