2015-07-15 5 views
3

У меня есть большой файл с 107635 строками и 3 столбцами: тема, области интереса (ROI) и номер пробной версии. ROI могут быть A, B, C, D, E, F. Что я хочу сделать, так это сохранить только те испытания, в которых в столбце ROI у меня есть последовательная последовательность B, C, D, когда B появляется. Неважно, сколько раз происходят B, C и D.R - идентифицировать последовательные последовательности

В приведенном ниже примере я могу сохранить ntrial 78 и 201, потому что в первый раз, когда появился B, следовали C и D. Однако мне нужно удалить ntrial 10 и 400. В испытании 10 B, C и D не являются последовательными. В испытании 400 в первый раз, когда появляется B, B не следует C и D.

Для вывода мне нужен столбец со значением 1 для испытаний, которые должны храниться в каждой строке, и значение 0 для строк, соответствующих удаляемым испытаниям.

Любое предложение о том, как создать код, который может автоматизировать процедуру, без визуального осмотра каждой пробной версии?

Большое спасибо!

subject ROI ntrial output 
sbj05 A 78  1 
sbj05 A 78  1 
sbj05 A 78  1 
sbj05 A 78  1 
sbj05 A 78  1 
sbj05 A 78  1 
sbj05 B 78  1 
sbj05 B 78  1 
sbj05 C 78  1 
sbj05 D 78  1 
sbj05 E 78  1 
sbj05 E 78  1 
sbj05 E 78  1 
sbj05 A 201 1 
sbj05 A 201 1 
sbj05 A 201 1 
sbj05 A 201 1 
sbj05 A 201 1 
sbj05 B 201 1 
sbj05 C 201 1 
sbj05 D 201 1 
sbj05 E 201 1 
sbj05 E 201 1 
sbj05 E 201 1 
sbj05 F 201 1 
sbj05 F 201 1 
sbj05 A 10  0 
sbj05 A 10  0 
sbj05 A 10  0 
sbj05 A 10  0 
sbj05 B 10  0 
sbj05 A 10  0 
sbj05 C 10  0 
sbj05 D 10  0 
sbj05 E 10  0 
sbj05 E 10  0 
sbj05 A 400 0 
sbj05 A 400 0 
sbj05 A 400 0 
sbj05 B 400 0 
sbj05 A 400 0 
sbj05 B 400 0 
sbj05 C 400 0 
sbj05 C 400 0 
sbj05 C 400 0 
sbj05 D 400 0 
sbj05 E 400 0 
sbj05 E 400 0 
sbj05 D 400 0 
+2

В ntrial 78 это 'BBCD', поэтому он не является первым B, за которым следует C D – akrun

+1

Пожалуйста, укажите желаемый результат, так как ваше описание немного запутанно. –

+0

@akrun, что я подразумеваю под первым B, это первый раз, когда B появляется в столбце ROI. Тогда для меня не имеет значения, если за B следует множество B, прежде чем перейти на C и D. Важно то, что единственными последовательными буквами, которые могут появляться, являются «B», «C» и «D». Надеюсь, он уточнит .. – dede

ответ

4

Вот попытка использования data.table и stringi

Первый, я определяю некоторые вспомогательные функции, которые помогут мне обнаружить первые accurances из B в группе и подтвердить, что они следуют правильной последовательности

Myfunc <- function(x) { 
       which(x == "B")[1L] == 
       stri_locate_first_regex(paste(x, collapse = ""), 'B*CD')[, 1L] 
       } 

Затем, реализация прямой

library(data.table) 
library(stringi) 
setDT(df)[, if(Myfunc(ROI)) .SD, by = .(subject, ntrial)] 
#  subject ntrial ROI 
# 1: sbj05  78 A 
# 2: sbj05  78 A 
# 3: sbj05  78 A 
# 4: sbj05  78 A 
# 5: sbj05  78 A 
# 6: sbj05  78 A 
# 7: sbj05  78 B 
# 8: sbj05  78 B 
# 9: sbj05  78 C 
# 10: sbj05  78 D 
# 11: sbj05  78 E 
# 12: sbj05  78 E 
# 13: sbj05  78 E 
# 14: sbj05 201 A 
# 15: sbj05 201 A 
# 16: sbj05 201 A 
# 17: sbj05 201 A 
# 18: sbj05 201 A 
# 19: sbj05 201 B 
# 20: sbj05 201 C 
# 21: sbj05 201 D 
# 22: sbj05 201 E 
# 23: sbj05 201 E 
# 24: sbj05 201 E 
# 25: sbj05 201 F 
# 26: sbj05 201 F 

Или, если вы просто хотите дополнительный столбец можно сделать

setDT(df)[, output := +Myfunc(ROI), by = .(subject, ntrial)] 
+0

Как можно будет использовать ваше решение, если вместо «B» , «C» и «D» мы имеем строки букв типа «_target1», «_target2», «_target3», в которых первая часть строки отличается для каждого наблюдения, но вторая часть строки такая же (например, , abcdsgf_target1, hjgjkfkgkr_target1, jjjjdsds_target2, ljkg_target3, hascj_target3)? – dede

+0

Я не помню, каков был исходный вопрос, но для того, чтобы извлечь эти строки, вы могли бы просто использовать что-то вроде 'sub (". * _ "," ", ROI)' (untested), а затем соответствующим образом скорректировать код. –

1

Вот еще один:

idx <- sapply(split(df, df$ntrial), function(x) { 
    B <- with(rle(x$ROI == "B"), sum(lengths[seq(which.max(values))])) 
    all(x$ROI[B:(B+2)] == c("B", "C", "D")) 
}) 
subset(df, ntrial %in% names(which(idx))) 
0

base R путь с match и rle:

df$ output <- +as.logical(ave(as.character(df$ROI), df$ntrial, FUN=function(x) {rle(x[match("B",x):length(x)])$values[2] == "C"})) 
# subject ROI ntrial output 
# 1 sbj05 A  78  1 
# 2 sbj05 A  78  1 
# 3 sbj05 A  78  1 
# 4 sbj05 A  78  1 
# 5 sbj05 A  78  1 
# 6 sbj05 A  78  1 
# 7 sbj05 B  78  1 
# 8 sbj05 B  78  1 
# 9 sbj05 C  78  1 
# 10 sbj05 D  78  1 
# 11 sbj05 E  78  1 
# 12 sbj05 E  78  1 
# 13 sbj05 E  78  1 
# 14 sbj05 A 201  1 
# 15 sbj05 A 201  1 
# 16 sbj05 A 201  1 
# 17 sbj05 A 201  1 
# 18 sbj05 A 201  1 
# 19 sbj05 B 201  1 
# 20 sbj05 C 201  1 
# 21 sbj05 D 201  1 
# 22 sbj05 E 201  1 
# 23 sbj05 E 201  1 
# 24 sbj05 E 201  1 
# 25 sbj05 F 201  1 
# 26 sbj05 F 201  1 
# 27 sbj05 A  10  0 
# 28 sbj05 A  10  0 
# 29 sbj05 A  10  0 
# 30 sbj05 A  10  0 
# 31 sbj05 B  10  0 
# 32 sbj05 A  10  0 
# 33 sbj05 C  10  0 
# 34 sbj05 D  10  0 
# 35 sbj05 E  10  0 
# 36 sbj05 E  10  0 
# 37 sbj05 A 400  0 
# 38 sbj05 A 400  0 
# 39 sbj05 A 400  0 
# 40 sbj05 B 400  0 
# 41 sbj05 A 400  0 
# 42 sbj05 B 400  0 
# 43 sbj05 C 400  0 
# 44 sbj05 C 400  0 
# 45 sbj05 C 400  0 
# 46 sbj05 D 400  0 
# 47 sbj05 E 400  0 
# 48 sbj05 E 400  0 
# 49 sbj05 D 400  0