Попытка консолидировать пары выборок и их переменные на основе того, имеет ли пара выборок логическое значение TRUE или FALSE в одном или обоих типах выборки. некоторые пробы могут иметь только один тип пробы, но не более 1 пробы типа А и 1 пробы типа В.
для кадра данных ниже:
a b c d e f g h samples_name sample_type
1 FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE PAEEYP A
2 FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE PAEEYP B
3 FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE PAERAH A
4 FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE PAERAH B
5 FALSE FALSE FALSE TRUE TRUE FALSE FALSE FALSE PAKIYW A \\only has A sample
4 возможных значения 1) ЛОЖЬ = оба ЛОЖЬ; 2)A = ИСТИНА только для A; 3)B = ИСТИНА только для B, 4)ИСТИНА = оба варианта ИСТИНА
a b c d e f g h samples_name
1 FALSE B FALSE FALSE FALSE A FALSE FALSE PAEEYP
2 FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE PAERAH
3 FALSE FALSE FALSE A A FALSE FALSE FALSE PAKIYW
Я застрял и не знаю, как это сделать. Я предполагаю, что мне нужно разделить/сгруппировать их по имени образца, отсортировать их по типу образца, а затем применить некоторую функцию colwise ifelse в каждом подмножестве/группе перед объединением в фрейм данных. Я думал об использовании ddply для выполнения поднастройки и применения функции colwise, но я не могу понять. Почему-то я думаю, что слишком много думаю о проблеме, любая помощь будет оценена по достоинству.
Может быть, изменить заголовок вопроса на «Условное объединение логических векторов»…
Я столкнулся с некоторыми проблемами, потому что ваш желаемый результат смешивает логический и символьный...
Это решение не самое красивое. Он хакается на лету ;-).
Но, возможно, это направит вас в правильном направлении или вдохновит других на поиск лучших ответов...
образец данных
library( data.table )
DT <- fread("a b c d e f g h samples_name sample_type
FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE PAEEYP A
FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE PAEEYP B
FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE PAERAH A
FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE PAERAH B
FALSE FALSE FALSE TRUE TRUE FALSE FALSE FALSE PAKIYW A")
код
#melt to long
DT.melt <- melt( DT, id.vars = c( "samples_name", "sample_type" ) )
#set TRUE/FALSE to 1/0
DT.melt[, value := as.numeric( value )]
#only keep roes where value > 0
ans <- DT.melt[ !value == 0, ]
ans <- ans[, .(total = paste0(sample_type, collapse = "")), by = .(samples_name, variable)]
ans[ total == "AB", total := "TRUE"]
# samples_name variable total
# 1: PAEEYP b B
# 2: PAKIYW d A
# 3: PAKIYW e A
# 4: PAEEYP f A
# 5: PAERAH h TRUE
#create new melt without the sample_type
DT.melt2 <- melt( DT, id.vars = c( "samples_name" ), measure.vars = patterns("^[a-h]$") )
#set value to character, drop duplicates
DT.melt2 <- unique( DT.melt2[, value := as.character(value)], by = c("samples_name", "variable"))
#update join answer
DT.melt2[ ans, value := i.total, on = .(samples_name, variable)]
#and cast back to wide format
dcast(DT.melt2, samples_name ~ variable, value.var = "value")
выход
# samples_name a b c d e f g h
# 1: PAEEYP FALSE B FALSE FALSE FALSE A FALSE FALSE
# 2: PAERAH FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE
# 3: PAKIYW FALSE FALSE FALSE A A FALSE FALSE FALSE
Большое спасибо за решение, оно на самом деле выглядит аккуратно и еще раз поразило меня, насколько простым может быть решение. Я новичок в R и впервые сталкиваюсь с оператором := и функцией dcast. единственное, чего я не понимаю, так это того, как вы присоединяетесь к ответам с DT.melt2, можете ли вы объяснить, как на самом деле работаетDT.melt2[ ans, value := i.total, on = .(samples_name, variable)]
? Я не могу понять наличие 3 запятых внутри [ ], можно ли on =
?
Только что нашел этот пост в блоге, в котором подробно рассказывается о библиотеке data.table, и теперь я понимаю, как многие вещи работают с вашим примером, синтаксис с data.table на самом деле более прямолинеен по сравнению с dplyr, и производительность намного также лучше, я думаю, что с этого момента я буду использовать его больше, потому что я имею дело с довольно большими данными (> 300 000 строк). analyticsvidhya.com/blog/2016/05/…
Один из подходов, который вы затронули, состоит в том, чтобы разбить фрейм данных на списки на основе
samples_name
, используя что-то вродеsplit(df, f = df$samples_name)
, а затем применить функцию, используяlapply
, которая проходит через каждый столбец и проверяет ваши условия...