Rowsums с несколькими условиями

Я пытаюсь рассчитать совокупную сумму в строках с несколькими переменными.

Это мои данные для примера. У меня есть 5 идентификаторов пациентов и 4 переменные состояния. Если в условиях есть значение от «1 до 3», к общей сумме будет добавлено 1.

ID<-c("a","b","c","d","e")
cond1<-as.factor(sample(x=1:7,size=5,replace=TRUE))
cond2<-as.factor(sample(x=1:7,size=5,replace=TRUE))
cond3<-as.factor(sample(x=1:7,size=5,replace=TRUE))
cond4<-as.factor(sample(x=1:7,size=5,replace=TRUE))
df<-data.frame(ID,cond1,cond2,cond3,cond4)
df

  ID cond1 cond2 cond3 cond4
1  a     2     7     6     6
2  b     7     2     3     6
3  c     4     3     1     4
4  d     7     3     3     6
5  e     6     7     7     3

Я использую код rowSums со следующим утверждением. Однако во 2-й строке, хотя cond2 равно 2, а cond3 равно 3, cumsum было не «2», а «1». На 4 ряду такая же проблема.

df$cumsum<-rowSums(df[,2:5]==c(1,2,3),na.rm=TRUE)
df
  ID cond1 cond2 cond3 cond4 cumsum
1  a     2     7     6     6      0
2  b     7     2     3     6      1
3  c     4     3     1     4      1
4  d     7     3     3     6      1
5  e     6     7     7     3      0

Как сделать его накопительным? Я был бы очень признателен за вашу помощь.

Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
634
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Для сравнения более чем одного элемента используйте %in%, но %in% работает с vector. Итак, мы перебираем столбцы с помощью lapply/sapply, а затем выполняем rowSums в логической матрице.

df$RSum <- rowSums(sapply(df[,2:5], `%in%`, 1:3))
df$RSum
#[1] 1 2 2 2 1

Если бы значения были числовыми, мы могли бы также использовать > или <

df$RSum <- rowSums(df[, 2:5] >=1 & df[, 2:5] <=3)

данные

df <- structure(list(ID = c("a", "b", "c", "d", "e"), cond1 = c(2L, 
7L, 4L, 7L, 6L), cond2 = c(7L, 2L, 3L, 3L, 7L), cond3 = c(6L, 
3L, 1L, 3L, 7L), cond4 = c(6L, 6L, 4L, 6L, 3L)), 
class = "data.frame", row.names = c("1", 
"2", "3", "4", "5"))

Я предлагаю вам исправить две проблемы с вашими данными:

  1. Ваши данные широкие, а не длинные. Если бы ваши данные были давно отформатированы, ваш анализ был бы намного проще. Особенно это касается построения графиков.
  2. Ваши значения для каждого условия являются факторами. Это затрудняет сравнение и может привести к некоторым трудным для обнаружения ошибкам. Если вы внимательно посмотрите на ответ @akrun, вы заметите, что значения являются целыми (числовыми).

Тем не менее, я предлагаю data.table решение:

# 1. load libraries and make df a data.table:
library(data.table)
setDT(df)

# 2. make the wide table a long one
melt(df, id.vars = "ID")

# 3. with a long table, count the number of conditions that are in the 1:3 range for each ID. Notice I chained the first command with this second one:
melt(df, id.vars = "ID")[, sum(value %in% 1:3), by = ID]

Что дает результат:

   ID V1
1:  a  1
2:  b  2
3:  c  2
4:  d  2
5:  e  1

Вам нужно будет только запустить команды под номерами 1 и 3 (2 объединены в 3). См. ?data.table для получения дополнительной информации.

Подробнее о широких и длинных можно прочитать в статьях википедия и Ответ Майка Уайза.

Данные, которые я использовал, такие же, как у @akrun:

df <- structure(list(ID = c("a", "b", "c", "d", "e"),
                          cond1 = c(2L, 7L, 4L, 7L, 6L), 
                          cond2 = c(7L, 2L, 3L, 3L, 7L), 
                          cond3 = c(6L, 3L, 1L, 3L, 7L), 
                          cond4 = c(6L, 6L, 4L, 6L, 3L)), 
               class = "data.frame", 
               row.names = c("1", "2", "3", "4", "5"))

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