Цвет ячеек в зависимости от их значения для каждой строки фрейма данных

У меня есть фрейм данных, который выглядит так:

          header1  header2  header3  header4  ...
rowname1     1        2        3        4
rowname2     4        3        2        1
rowname3     2        4        1        3
rowname4     1        4        3        2
...

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

Пример того, что я хотел бы получить: Цвет ячеек в зависимости от их значения для каждой строки фрейма данных

Не могли бы вы помочь мне в решении этого вопроса?

Вы можете использовать пакет kableExtra. Здесь — отличное руководство.

symbolrush 08.04.2019 11:47

и, возможно, еще несколько альтернативных вариантов здесь

user20650 08.04.2019 11:55
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
276
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вот возможность с DT.

dat <- data.frame(
  V1 = rpois(6,5), 
  V2 = rpois(6,5), 
  V3 = rpois(6,5), 
  V4 = rpois(6,5),
  V5 = rpois(6,5),
  V6 = rpois(6,5)
)

library(DT)

js <- c(
  "function(row, data, num, index){",
  "  data.shift();", # remove row name
  "  var min = Math.min.apply(null, data);",
  "  var max = Math.max.apply(null, data);",
  "  for(var i=0; i<data.length; i++){",
  "    var f = (data[i] - min)/(max-min);",
  "    var h = 120*f;",
  "    var color = 'hsl(' + h + ', 100%, 50%)';",
  "    $('td:eq('+(i+1)+')', row).css('background-color', color);",
  "  }",
  "}"  
)


datatable(dat, options = list(rowCallback = JS(js)))

Чтобы добавить черные границы, выполните

datatable(dat, options = list(rowCallback = JS(js))) %>% 
  formatStyle(1:(ncol(dat)-1), `border-right` = "solid 1px")

Приведенное выше решение предполагает, что вы отображаете имена строк в таблице. Если вы не хотите отображать имена строк, выполните следующие действия:

js <- c(
  "function(row, data, num, index){",
  "  var min = Math.min.apply(null, data);",
  "  var max = Math.max.apply(null, data);",
  "  for(var i=0; i<data.length; i++){",
  "    var f = (data[i] - min)/(max-min);",
  "    var h = 120*f;",
  "    var color = 'hsl(' + h + ', 100%, 50%)';",
  "    $('td:eq('+i+')', row).css('background-color', color);",
  "  }",
  "}"  
)

datatable(dat, rownames = FALSE, options = list(rowCallback = JS(js)))

Редактировать

По просьбе ОП в чате, вот вариант. Вместо генерации цвета, пропорционального значению ячейки, он генерирует цвет, пропорциональный рангу значения ячейки.

js <- c(
  "function(row, data, num, index){",
  "  data.shift();", # remove row name
  "  var data_uniq = data.filter(function(item, index) {",
  "    if (data.indexOf(item) == index){",
  "      return item;",
  "  }}).sort(function(a,b){return a-b});",
  "  var n = data_uniq.length;",
  "  var ranks = data.slice().map(function(v){ return data_uniq.indexOf(v) });",
  "  for(var i=0; i<data.length; i++){",
  "    var f = ranks[i]/(n-1);",
  "    var h = 120*f;",
  "    var color = 'hsl(' + h + ', 100%, 50%)';",
  "    $('td:eq('+(i+1)+')', row).css('background-color', color);",
  "  }",
  "}"  
)

dat <- as.data.frame(matrix(round(rnorm(24),2), ncol=8))
datatable(dat, options = list(rowCallback = JS(js)))

Я обнаружил, что цвета стали более отчетливыми, заменив var h = 120*f; на

var h = 60*(1 + Math.tan(2*f-1)/Math.tan(1));

Спасибо за Ваш ответ. Я попробовал это с моим фреймом данных, и он создает таблицу данных, как у вас ... но без цвета. У вас есть идеи, почему?

Valentin Dubois 08.04.2019 13:08

@ValentinDubois В вашем фрейме данных есть только числовые значения? И есть ли пропущенные значения?

Stéphane Laurent 08.04.2019 13:10

Только числовые значения и никаких пропущенных значений, или я так думаю. Обновлено: на самом деле кажется, что значения по какой-то причине не являются числовыми, и мы решим эту проблему.

Valentin Dubois 08.04.2019 13:17

Итак, теперь у меня есть цвета, но кажется, что цвета применяются ко всему набору значений, а не только к каждой строке.

Valentin Dubois 08.04.2019 15:29

Хорошо, я думаю, что это не работает из-за нечисловых имен строк. Я не уверен, что понимаю код «js», но я думаю, что он требует числового аргумента для «строки», верно?

Valentin Dubois 08.04.2019 16:04

@ValentinDubois Аааа, да, извините. Аргумент data соответствует одной строке. Действительно, имя строки является первым компонентом, и в этом проблема. Позвольте мне попытаться исправить это.

Stéphane Laurent 08.04.2019 16:11

@ValentinDubois Я обновил js. Не могли бы вы попробовать, пожалуйста? Теперь код должен принимать имена строк символов (data.shift() удаляет первый компонент, то есть имя строки).

Stéphane Laurent 08.04.2019 16:21

Большое спасибо, на этот раз все работает отлично! Извините, что злоупотребляю вашими знаниями, но не могли бы вы также добавить черные рамки для каждой ячейки, чтобы мы могли различать их? (особенно зеленые клетки, которые трудно отличить друг от друга). Спасибо большое за вашу помощь в любом случае!

Valentin Dubois 08.04.2019 16:29

Давайте продолжить обсуждение в чате.

Valentin Dubois 08.04.2019 17:07

Другие вопросы по теме