R heatmap с частями дискретизируют переменные в стороне ряда

У меня есть несколько тысяч наблюдений за горсткой факторов, что я превращаюсь в дискретные ценности 1/0 согласно минимальному значению за фактор, и я готовлю его в heatmap.2 (red=1, black=0). Это готовит комбинации, скажем, A+B+C+D, являющегося 1, комбинации 3 факторов, являющихся 1, комбинации 2 факторов, и т.д. Я хотел бы иметь части этих комбинаций, подготовленных в левой стороне вертикальная ось в heatmap.2:

nentries=10000
ci=rainbow(nentries)
set.seed=1
mean=10
## Generate some data (4 factors)
i = data.frame(
  a=round(abs(rnorm(nentries,mean-2))),
  b=round(abs(rnorm(nentries,mean-1))),
  c=round(abs(rnorm(nentries,mean+1))),
  d=round(abs(rnorm(nentries,mean+2)))
  )
minvalue = 10
# Discretise values to 1 or 0
m0 = matrix(as.numeric(i>minvalue),nrow=nrow(i))
# Remove rows with all zeros
m = m0[rowSums(m0)>0,]
# Reorder with 1,1,1,1 on top
ms =m[order(as.vector(m %*% matrix(2^((ncol(m)-1):0),ncol=1)), decreasing=TRUE),]
rowci = rainbow(nrow(ms))
colci = rainbow(ncol(ms))
heatmap(ms,
        Rowv=NA,
        labRow=" ",
        keep.dendro = FALSE,
        col=c("black","red"),
        RowSideColors=rowci,
        ColSideColors=colci,
        )

RowSideColors - прямо сейчас радуга с целым nrow (ms) цвета, и я хотел бы вместо этого иметь 1/0 комбинации для факторов и легенды. Что-то как: A+B+C+D 1% , B+C+D 10% , и т.д., рядом с RowSideColors. Какие-либо идеи?

1
nl ja de
Таким образом, то, что вы хотите, должно добавить легенду?
добавлено автор Julius, источник

2 ответы

Если я понимаю ваш вопрос правильно, вы хотите небольшое количество этикеток ряда, один для каждого блока? Это должно добиться цели

colnames(ms)=LETTERS[1:4]
limits=c(which(!duplicated(ms)),nrow(ms))
l=length(limits)
toname=round((limits[-l]+ limits[-1])/2)
freq=(limits[-1]-limits[-l])/nrow(ms)

rn=rep("", nrow(ms))
for(i in toname) rn[i]=paste(colnames(ms)[which(ms[i,]==1)],collapse="")
rn[toname]=paste(rn[toname], ": ", sprintf( "%.5f", freq ), "%")

heatmap(ms, Rowv=NA, labRow=rn, col=c("black","red"))

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

5
добавлено
Блестящий! Это точно, что я искал!
добавлено автор 719016, источник

Если я понимаю ваш вопрос правильно, вы хотите небольшое количество этикеток ряда, один для каждого блока? Это должно добиться цели

colnames(ms)=LETTERS[1:4]
limits=c(which(!duplicated(ms)),nrow(ms))
l=length(limits)
toname=round((limits[-l]+ limits[-1])/2)
freq=(limits[-1]-limits[-l])/nrow(ms)

rn=rep("", nrow(ms))
for(i in toname) rn[i]=paste(colnames(ms)[which(ms[i,]==1)],collapse="")
rn[toname]=paste(rn[toname], ": ", sprintf( "%.5f", freq ), "%")

heatmap(ms, Rowv=NA, labRow=rn, col=c("black","red"))

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

5
добавлено
Блестящий! Это точно, что я искал!
добавлено автор 719016, источник