2010-02-10 1 views
3

Я использую R, и я новичок. У меня есть два больших списка (каждый 30K элементов). Один из них называется descriptions и где каждый элемент является (может быть) обозначенной строкой. Другой называется probes, где каждый элемент является числом. Мне нужно сделать словарь, который отображает probes на что-то в descriptions, если это что-то есть. Вот как я буду об этом:Замена R-thonic для простых циклов, содержащих условие

probe2gene <- list() 
for (i in 1:length(probes)){ 
strings<-strsplit(descriptions[i]), '//') 
if (length(strings[[1]]) > 1){ 
    probe2gene[probes[i]] = strings[[1]][2] 
} 
} 

Который работает хорошо, но, кажется, медленно, гораздо медленнее, чем примерно эквивалентный питона:

probe2gene = {} 
for p,d in zip(probes, descriptions): 
    try: 
    probe2gene[p] = descriptions.split('//')[1] 
    except IndexError: 
    pass 

Мой вопрос: есть ли «R-thonic» способ делать то, что я пытаюсь сделать? R manual entry on for loops предполагает, что такие петли редки. Есть ли лучшее решение?

Edit: типичный хороший "описание" выглядит следующим образом:

"NM_009826 // Rb1cc1 // RB1-inducible coiled-coil 1 // 1 A2 // 12421 /// AB070619 // Rb1cc1 // RB1-inducible coiled-coil 1 // 1 A2 // 12421 /// ENSMUST00000027040 // Rb1cc1 // RB1-inducible coiled-coil 1 // 1 A2 // 12421" 

плохой «Описание: выглядит как этот

"-----" 

, хотя это вполне может быть легко некоторые другие не-very- Полезная строка: каждый зонд представляет собой просто номер. Векторы имеют одинаковую длину и полностью соответствуют друг другу, т.е. probe[i] соответствует description[i].

+0

«R-thonic» :) Разве это не Ric? – Skilldrick

+0

Небольшой образец данных будет полезен. – Shane

+1

Это определенно «пиратский». – Harlan

ответ

3

Это обычно лучше в R, если вы используете различные прикладные функции, а не цикл. Я думаю, что это решает вашу проблему; единственным недостатком является то, что вам нужно использовать строковые ключи.

> descriptions <- c("foo//bar", "") 
> probes <- c(10, 20) 
> probe2gene <- lapply(strsplit(descriptions, "//"), function (x) x[2]) 
> names(probe2gene) <- probes 
> probe2gene <- probe2gene[!is.na(probe2gene)] 
> probe2gene[["10"]] 
[1] "bar" 

К сожалению, у R нет хорошего типа словаря/карты. Самое близкое, что я нашел, - это использование списков в виде карты из строки в ценность. Кажется, это идиоматично, но это уродливо.

+0

Спасибо! Это намного быстрее. Если бы такие объекты, как «strsplit», могли быть применены ко всем векторам. Ухоженная! –

2

Если я правильно понимаю, вы ищете, чтобы сохранить каждую комбинацию зондов и описание, где в описании содержится более одного (разделенного) значения?

Зонд и описание такой же длины?

Это своего рода грязный, но быстрый первый проход на него?

a <- list("a","b","c") 
b <- list(c("a","b"),c("DEF","ABC"),c("Z")) 

names(b) <- a 
matches <- which(lapply(b, length)>1) #several ways to do this 
b <- lapply(b[matches], function(x) x[2]) #keeps the second element only 

Это моя первая попытка. Если у вас есть образец набора данных, который будет очень полезен.

С наилучшими пожеланиями,

Jay

+0

Трудно быть первым ответчиком;) – Jay

0

Другим способом.

probe<-c(4,3,1) 
gene<-c('red//hair','strange','blue//blood') 
probe2gene<-character() 
probe2gene[probe]<-sapply(strsplit(gene,'//'),'[',2) 
probe2gene 
[1] "blood" NA  NA  "hair" 

В sapply, мы воспользуемся тем фактом, что в R оператор Подменю также является функция под названием «[», к которому мы можем передать индекс в качестве аргумента. Кроме того, индекс вне диапазона не вызывает ошибку, но дает значение NA. В левой части той же строки мы используем тот факт, что мы можем передать вектор индексов в любом порядке и с пробелами.

0

Вот еще один подход, который должен быть быстрым. Обратите внимание, что это не удалите пустые описания.Его можно было бы адаптировать для этого, или вы, , могли бы очистить их на этапе последующей обработки, используя lapply. Является ли случай , что у вас никогда не будет допустимого описания длины один?

make_desc <- function(n) 
{ 
    word <- function(x) paste(sample(letters, 5, replace=TRUE), collapse = "") 
    if (runif(1) < 0.70) 
     paste(sapply(seq_len(n), word), collapse = "//") 
    else 
     "----" 
} 

description <- sapply(seq_len(10), make_desc) 
probes <- seq_len(length(description)) 

desc_parts <- strsplit(description, "//", fixed=TRUE, useBytes=TRUE) 
lens <- sapply(desc_parts, length) 
probes_expand <- rep(probes, lens) 
ans <- split(unlist(desc_parts), probes_expand) 


> description 
[1] "fmbec"                
[2] "----"                 
[3] "----"                 
[4] "frrii//yjxsa//wvkce//xbpkc"           
[5] "kazzp//ifrlz//ztnkh//dtwow//aqvcm"         
[6] "stupm//ncqhx//zaakn//kjymf//swvsr//zsexu"        
[7] "wajit//sajgr//cttzf//uagwy//qtuyh//iyiue//xelrq"      
[8] "nirex//awvnw//bvexw//mmzdp//lvetr//xvahy//qhgym//ggdax"    
[9] "----"                 
[10] "ubabx//tvqrd//vcxsp//rjshu//gbmvj//fbkea//smrgm//qfmpy//tpudu//qpjbu" 


> ans[[3]] 
[1] "----" 
> ans[[4]] 
[1] "frrii" "yjxsa" "wvkce" "xbpkc" 
Смежные вопросы