2016-11-22 8 views
1

Я хотел бы извлечь элементы из столбца в кадре данных на основе критериев, относящихся к значениям в других столбцах. Эти критерии приведены в виде списка, связывающего имена столбцов со значениями. Конечной целью является использование этих элементов для выбора столбцов по имени в другой структуре данных.Извлечение элементов из кадра данных R с использованием критериев, указанных как список (column_name = value)

Вот кадр пример данных:

> experimental_plan 
    lib genotype treatment replicate 
1 A  WT normal   1 
2 B  WT  hot   1 
3 C  mut normal   1 
4 D  mut  hot   1 
5 E  WT normal   2 
6 F  WT  hot   2 
7 G  mut normal   2 
8 H  mut  hot   2 

И мои критерии выбора кодируются в виде следующего списка:

> ref_condition = list(genotype="WT", treatment="normal") 

Я хочу, чтобы извлечь элементы в «Lib» колонку, где line ref_condition, то есть «A» и «E».

1) Я могу получить столбцы использовать для выбора с помощью names в моем списке критериев выбора:

> experimental_plan[, names(ref_condition)] 
    genotype treatment 
1  WT normal 
2  WT  hot 
3  mut normal 
4  mut  hot 
5  WT normal 
6  WT  hot 
7  mut normal 
8  mut  hot 

2) Я могу проверить, соответствуют ли полученные линии мои критерии выбора:

> experimental_plan[, names(ref_condition)] == ref_condition 
    genotype treatment 
[1,]  TRUE  TRUE 
[2,]  TRUE  FALSE 
[3,] FALSE  TRUE 
[4,] FALSE  FALSE 
[5,]  TRUE  TRUE 
[6,]  TRUE  FALSE 
[7,] FALSE  TRUE 
[8,] FALSE  FALSE 
> selection_vector <- apply(experimental_plan[, names(ref_condition)] == ref_condition, 1, all) 
> selection_vector 
[1] TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE 

(Я думаю, что этот шаг, с apply не особенно изящный. Должен быть лучший способ.)

3) Этот булев вектор c использоваться для выбора соответствующих строк:

> selected_lines <- experimental_plan[selection_vector,] 
> selected_lines 
    lib genotype treatment replicate 
1 A  WT normal   1 
5 E  WT normal   2 

4) С этого момента, я знаю, как использовать dplyr для выбора пунктов Я заинтересован в:

> lib1 <- filter(selected_lines, replicate=="1") %>% select(lib) %>% unlist() 
> lib2 <- filter(selected_lines, replicate=="2") %>% select(lib) %>% unlist() 
> lib1 
lib 
    A 
Levels: A B C D E F G H 
> lib2 
lib 
    E 
Levels: A B C D E F G H 

Может dplyr (или другие умные методы) можно использовать на более ранних этапах?

5) Эти элементы соответствуют именам столбцов в другой структуре данных (здесь названо counts_data). Я использую их, чтобы извлечь соответствующие столбцы и поместить их в список, связанный с повторными номерами, названиями:

> counts_1 <- counts_data[, lib1] 
> counts_2 <- counts_data[, lib2] 
> list_of_counts <- list("1" <- counts_1, "2" <- counts_2) 

(В идеале, я хотел бы обобщить код так, что мне не нужно знать (я имею в виду , «hard-code them»), какие разные значения существуют в столбце «replicate»: может быть любое количество репликатов для данной комбинации характеристик «генотип» и «лечение», и я хочу, чтобы мой последний список содержал данные от counts_data, относящихся к соответствующим элементам «lib».)

Есть ли способ сделать весь процесс более элегантно/эффективно?

ответ

1

Думаю, вы можете использовать данные.Таблица для этого с помощью ключа

library(data.table) 
test <- data.table(lib = LETTERS[1:8], 
      genotype = rep(c("WT","WT","mut","mut"),2), 
      treatment = rep(c("normal","hot"),4), 
      replicate = c(rep(1,4),rep(2,4))) 
setkeyv(test,c("genotype","treatment")) 
ref_condition = list(genotype="WT", treatment="normal") 
test[ref_condition,lib] 

Это дает

[1] «А», «Е»

Можно, конечно, использовать lapply в цикле по списку условий испытаний ,

+1

Fyi, последняя рекомендация - использовать 'on' в большинстве случаев вместо того, чтобы беспокоиться о ключах: http://stackoverflow.com/a/20057411/ – Frank

+0

Я пробовал это. Он работал с вашим примером, но в моем фактическом коде я получил «Ошибка в'. .Data.frame' (x, i, j): object 'lib' not found ". Тест с вашим кодом показывает, что использование «lib» вместо lib не дает ожидаемых результатов, но я все равно пытался, и теперь я получаю «Ошибка в xj [i]: недопустимый тип индекса« list »» Я использовал ' имена (ref_condition) 'при настройке ключей. Тест с вашим кодом говорит мне, что это не является причиной проблемы. Что может привести к таким ошибкам? – bli

+0

Я думаю, что вы по-прежнему используете data.frame вместо data.table. Скажите, что ваши данные находятся в кадре данных «df», а затем используйте dt <- as.data.table (df) – Martin