Как подсчитать, сколько единиц в каждой строке по заданному количеству столбцов в зависимости от количества отсутствующих/NA, присутствующих в каждой строке в R?

Я хочу создать новый столбец «X11», который суммирует все единицы условно в зависимости от того, сколько NA имеется в выбранном количестве столбцов. В данном случае я рассматриваю 4 переменные: X1, X2, X3 и X4.

Пример: если есть 1 NA, то я хочу посмотреть на оставшиеся 3 переменные, которые имеют значения, и посчитать, сколько там единиц. Если есть 2 NA, то я хочу посмотреть на оставшиеся 2 переменные и посчитать, сколько там единиц. Если у меня есть 3 NA, то я хочу посмотреть на оставшуюся 1 переменную и определить, равна ли она 1. Если у меня есть все 4 NA, то это даст мне 0.

У меня есть эти данные:

df <- data.frame(replicate(10,sample(0:2, 10, rep=TRUE)))
df <- replace(df, df == 0, NA)

Мой фрейм данных выглядит так:

   X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
1   1  1 NA  1 NA NA NA  1  1   2
2  NA  1  1 NA  2 NA  2  2 NA   1
3   1 NA  1  1 NA NA  1  2 NA   1
4   2  2  2  1  1  2  1 NA  2   2
5  NA  2 NA  2 NA  2  1 NA  1   1
6   2  2  1  1  2 NA  1  2  1   1
7   1  2 NA NA  2  1  1 NA NA   1
8   2  2 NA NA  1 NA NA  2 NA   1
9   1 NA  1  2  2  1  2 NA NA   1
10 NA  2  1 NA NA NA NA  2  2  NA

Я хочу, чтобы мой результат выглядел так:

   X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11
1   1  1 NA  1 NA NA NA  1  1   2   3
2  NA  1  1 NA  2 NA  2  2 NA   1   2
3   1 NA  1  1 NA NA  1  2 NA   1   3
4   2  2  2  1  1  2  1 NA  2   2   1
5  NA  2 NA  2 NA  2  1 NA  1   1   0
6   2  2  1  1  2 NA  1  2  1   1   2
7   1  2 NA NA  2  1  1 NA NA   1   1
8   2  2 NA NA  1 NA NA  2 NA   1   0
9   1 NA  1  2  2  1  2 NA NA   1   2
10 NA  2  1 NA NA NA NA  2  2  NA   1

Вот пример моего текущего кода:

vars <- c("X1", "X2", "X3", "X4")
df <- df %>%
   mutate(missing_vars = rowSums(across(vars, ~is.na(.))),
          nonmissing_vars = 7-vars)

df <- df %>%
  mutate(zero_na = case_when(missing_vars == 0 & (X1 == 2 & X2 == 2 & X3 == 2 & X4 == 2) ~ 1,
                                (missing_vars == 0 & (X1 == 1 & X2 == 2 & X3 == 2 & X4 == 2) |
                                   (X1 == 2 & X2 == 1 & X3 == 2 & X4 == 2) |
                                   (X1 == 2 & X2 == 2 & X3 == 1 & X4 == 2) |
                                   (X1 == 2 & X2 == 2 & X3 == 2 & X4 == 1)) ~ 2,
                                (missing_vars == 0 & (X1 == 1 & X2 == 1 & X3 == 2 & X4 == 2) |
                                   (X1 == 1 & X2 == 2 & X3 == 1 & X4 == 2) |
                                   (X1 == 1 & X2 == 2 & X3 == 2 & X4 == 1) |
                                   (X1 == 2 & X2 == 1 & X3 == 1 & X4 == 2) |
                                   (X1 == 2 & X2 == 2 & X3 == 1 & X4 == 1) |
                                   (X1 == 2 & X2 == 1 & X3 == 2 & X4 == 1)) ~ 3,
                                (missing_vars == 0 & (X1 == 1 & X2 == 1 & X3 == 1 & X4 == 2) |
                                   (X1 == 1 & X2 == 1 & X3 == 2 & X4 == 1) |
                                   (X1 == 1 & X2 == 2 & X3 == 1 & X4 == 1) |
                                   (X1 == 2 & X2 == 1 & X3 == 1 & X4 == 1)) ~ 4,
                                missing_vars == 0 & (X1 == 1 & X2 == 1 & X3 == 1 & X4 == 1) ~ 5))

brfss <- brfss %>%
  mutate(one_na = case_when(missing_vars == 1 & (is.na(X1) & X2 == 2 & X3 == 2 & X4 == 2) ~ 1,
                                       missing_vars == 1 & (X1 == 2 & is.na(X2) & X3 == 2 & X4 == 2) ~ 1,
                                       missing_vars == 1 & (X1 == 2 & X2 == 2 & is.na(X3) & X4 == 2) ~ 1,
                                       missing_vars == 1 & (X1 == 2 & X2 == 2 & X3 == 2 & is.na(X4)) ~ 1,
                                       missing_vars == 1 & (is.na(X1) & X2 == 1 & X3 == 2 & X4 == 2) ~ 2,
                                       missing_vars == 1 & (X1 == 1 & is.na(X2) & X3 == 2 & X4 == 2) ~ 2,
                                       missing_vars == 1 & (X1 == 1 & X2 == 2 & is.na(X3) & X4 == 2) ~ 2,
                                       missing_vars == 1 & (X1 == 1 & X2 == 2 & X3 == 2 & is.na(X4)) ~ 2,
                                       missing_vars == 1 & (is.na(X1) & X2 == 2 & X3 == 1 & X4 == 2) ~ 2,
                                       missing_vars == 1 & (X1 == 2 & is.na(X2) & X3 == 1 & X4 == 2) ~ 2,
                                       missing_vars == 1 & (X1 == 2 & X2 == 1 & is.na(X3) & X4 == 2) ~ 2,
                                       missing_vars == 1 & (X1 == 2 & X2 == 1 & X3 == 2 & is.na(X4)) ~ 2,
                                       missing_vars == 1 & (is.na(X1) & X2 == 2 & X3 == 2 & X4 == 1) ~ 2,
                                       missing_vars == 1 & (X1 == 2 & is.na(X2) & X3 == 2 & X4 == 1) ~ 2,
                                       missing_vars == 1 & (X1 == 2 & X2 == 2 & is.na(X3) & X4 == 1) ~ 2,
                                       missing_vars == 1 & (X1 == 2 & X2 == 2 & X3 == 1 & is.na(X4)) ~ 2,
                                       missing_vars == 1 & (is.na(X1) & X2 == 1 & X3 == 1 & X4 == 2) ~ 3,
                                       missing_vars == 1 & (X1 == 1 & is.na(X2) & X3 == 1 & X4 == 2) ~ 3,
                                       missing_vars == 1 & (X1 == 1 & X2 == 1 & is.na(X3) & X4 == 2) ~ 3,
                                       missing_vars == 1 & (X1 == 1 & X2 == 1 & X3 == 2 & is.na(X4)) ~ 3,
                                       missing_vars == 1 & (is.na(X1) & X2 == 2 & X3 == 1 & X4 == 1) ~ 3,
                                       missing_vars == 1 & (X1 == 2 & is.na(X2) & X3 == 1 & X4 == 1) ~ 3,
                                       missing_vars == 1 & (X1 == 2 & X2 == 1 & is.na(X3) & X4 == 1) ~ 3,
                                       missing_vars == 1 & (X1 == 2 & X2 == 1 & X3 == 1 & is.na(X4)) ~ 3,
                                       missing_vars == 1 & (is.na(X1) & X2 == 1 & X3 == 2 & X4 == 1) ~ 3,
                                       missing_vars == 1 & (X1 == 1 & is.na(X2) & X3 == 2 & X4 == 1) ~ 3,
                                       missing_vars == 1 & (X1 == 1 & X2 == 2 & is.na(X3) & X4 == 1) ~ 3,
                                       missing_vars == 1 & (X1 == 1 & X2 == 2 & X3 == 1 & is.na(X4)) ~ 3,
                                       missing_vars == 1 & (is.na(X1) & X2 == 1 & X3 == 1 & X4 == 1) ~ 4,
                                       missing_vars == 1 & (X1 == 1 & is.na(X2) & X3 == 1 & X4 == 1) ~ 4,
                                       missing_vars == 1 & (X1 == 1 & X2 == 1 & is.na(X3) & X4 == 1) ~ 4,
                                       missing_vars == 1 & (X1 == 1 & X2 == 1 & X3 == 1 & is.na(X4)) ~ 4))

Я повторяю это с каждой комбинацией для 2 NA, 3 NA, а затем 4 NA, а затем суммирую «zero_na», «one_na» и т. д., чтобы получить окончательный подсчет значения под X11.

Однако в настоящее время у меня есть около 300 000 наблюдений, и мне нужно сделать это по 7 различным переменным с разным количеством NA, 1 и 2. Мне придется написать нелепое количество комбинаций, и я просто хотел знать, есть ли более эффективный способ написания этого кода?

Заранее большое спасибо!

Возможно, другой способ сформулировать это так: «если 1 НП, то сколько единиц в оставшихся выбранных столбцах; если 2 НП, то сколько двойок в оставшихся выбранных столбцах; если 3 НП , тогда сколько единиц в остальных выбранных столбцах?"

ayy__bee 19.08.2024 21:53
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
50
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

Попробуйте это:

df["X11"] = apply(df[,c(1:4)],1,\(s) sum(s==1,na.rm=T))

Вы можете добиться того же результата, используя rowwise() и c_across(), если вы неравнодушны к решению dplyr.

df %>% rowwise() %>% mutate(x11 = sum(c_across(X1:X4)==1, na.rm=T))

Выход:

   X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11
1   1  1 NA  1 NA NA NA  1  1   2   3
2  NA  1  1 NA  2 NA  2  2 NA   1   2
3   1 NA  1  1 NA NA  1  2 NA   1   3
4   2  2  2  1  1  2  1 NA  2   2   1
5  NA  2 NA  2 NA  2  1 NA  1   1   0
6   2  2  1  1  2 NA  1  2  1   1   2
7   1  2 NA NA  2  1  1 NA NA   1   1
8   2  2 NA NA  1 NA NA  2 NA   1   0
9   1 NA  1  2  2  1  2 NA NA   1   2
10 NA  2  1 NA NA NA NA  2  2  NA   1

Спасибо! В итоге я использовал: df <- df %>% mutate(X11 = rowSums(across(X1:X4)==1, na.rm=T)) потому что rowwise() и c_across() заняли немного больше времени. Я ценю вашу помощь!!!

ayy__bee 21.08.2024 17:35

Просто используйте rowSums():

  df$X11 = rowSums(df[1L:4L] == 1L, na.rm = TRUE)
  df
#>    X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11
#> 1   1  1 NA  1 NA NA NA  1  1   2   3
#> 2  NA  1  1 NA  2 NA  2  2 NA   1   2
#> 3   1 NA  1  1 NA NA  1  2 NA   1   3
#> 4   2  2  2  1  1  2  1 NA  2   2   1
#> 5  NA  2 NA  2 NA  2  1 NA  1   1   0
#> 6   2  2  1  1  2 NA  1  2  1   1   2
#> 7   1  2 NA NA  2  1  1 NA NA   1   1
#> 8   2  2 NA NA  1 NA NA  2 NA   1   0
#> 9   1 NA  1  2  2  1  2 NA NA   1   2
#> 10 NA  2  1 NA NA NA NA  2  2  NA   1

и укажите na.rm = TRUE.


Примечание

Предоставленные данные

  df = read.table(text = "   X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
1   1  1 NA  1 NA NA NA  1  1   2
2  NA  1  1 NA  2 NA  2  2 NA   1
3   1 NA  1  1 NA NA  1  2 NA   1
4   2  2  2  1  1  2  1 NA  2   2
5  NA  2 NA  2 NA  2  1 NA  1   1
6   2  2  1  1  2 NA  1  2  1   1
7   1  2 NA NA  2  1  1 NA NA   1
8   2  2 NA NA  1 NA NA  2 NA   1
9   1 NA  1  2  2  1  2 NA NA   1
10 NA  2  1 NA NA NA NA  2  2  NA", header = TRUE)

Вот трюк с ^ + is.na + rowSums

> df$X11 <- rowSums(!is.na(df[1:4]^NA))

> df
   X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11
1   1  1 NA  1 NA NA NA  1  1   2   3
2  NA  1  1 NA  2 NA  2  2 NA   1   2
3   1 NA  1  1 NA NA  1  2 NA   1   3
4   2  2  2  1  1  2  1 NA  2   2   1
5  NA  2 NA  2 NA  2  1 NA  1   1   0
6   2  2  1  1  2 NA  1  2  1   1   2
7   1  2 NA NA  2  1  1 NA NA   1   1
8   2  2 NA NA  1 NA NA  2 NA   1   0
9   1 NA  1  2  2  1  2 NA NA   1   2
10 NA  2  1 NA NA NA NA  2  2  NA   1

Это сработало. Спасибо!!

ayy__bee 21.08.2024 17:37

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