Как подмножить фрейм данных на основе совпадений с другим фреймом данных?

Я хочу написать цикл 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")

@SamR Я добавил ожидаемый результат и изменил имя exp().

melolili 15.02.2023 09:34
Laravel с Turbo JS
Laravel с Turbo JS
Turbo - это библиотека JavaScript для упрощения создания быстрых и высокоинтерактивных веб-приложений. Она работает с помощью техники под названием...
Типы ввода HTML: Лучшие практики и советы
Типы ввода HTML: Лучшие практики и советы
HTML, или HyperText Markup Language , является стандартным языком разметки, используемым для создания веб-страниц. Типы ввода HTML - это различные...
Аутсорсинг разработки PHP для индивидуальных веб-решений
Аутсорсинг разработки PHP для индивидуальных веб-решений
Услуги PHP-разработки могут быть экономически эффективным решением для компаний, которые ищут высококачественные услуги веб-разработки по доступным...
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
Слишком много useState? Давайте useReducer!
Слишком много useState? Давайте useReducer!
Современный фронтенд похож на старую добрую веб-разработку, но с одной загвоздкой: страница в браузере так же сложна, как и бэкенд.
Узнайте, как использовать теги &lt;ul&gt; и &lt;li&gt; для создания неупорядоченных списков в HTML
Узнайте, как использовать теги <ul> и <li> для создания неупорядоченных списков в HTML
HTML предоставляет множество тегов для структурирования и организации содержимого веб-страницы. Одним из наиболее часто используемых тегов для...
1
1
52
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

exp.df[colnames(exp.df) %in% rownames(subtypes),] && subtypes[subtypes$clust= = "1a",]

Базовый раствор R

Похоже, вы пытаетесь создать подмножество столбцов 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

Data.table подход

Я не люблю думать о 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)

Другие вопросы по теме