Создать столбец со значениями на основе других столбцов в R

Я хочу создать переменную, которая берет свое значение из 5 двоичных (Y/N) столбцов, чтобы каждое «ДА» считалось как 1, а каждое «НЕТ» как 0, поэтому каждое наблюдение будет иметь значение для этой новой переменной между 0 и 5.

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

new_variable <- if (variable_x == "YES"){increment(new_variable)}

но это кажется немного неэлегантным. Кто-нибудь знает, есть ли лучший способ сделать это?

Стоит ли изучать 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
52
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

R разработан так, что каждый TRUE уже является 1, а каждый FALSE уже является 0. Итак, если вы хотите добавить, сколько TRUE в c(TRUE, FALSE, TRUE), вы можете просто суммировать это:

sum(c(TRUE, FALSE, TRUE))

Так что в большинстве случаев вам действительно не нужно ничего настраивать. Если вы действительно, очень хотели это сделать, as.numeric сделает свою работу:

as.numeric(c(TRUE, FALSE, TRUE)

Выгодно кодировать двоичные значения как логические. В вашем случае вы можете сделать это на лету, используя == как в

sum(c("YES", "NO", "YES", "YES", "NO") == "YES")

Если в ваших данных есть какие-либо NA, вам придется принять решение и, вероятно, вы захотите использовать аргумент sums na.rm.

sum(c("YES", "YES", NA, "NO", "NO", NA) == "YES", na.rm = TRUE)

Насколько я понимаю ваш вопрос, вы можете использовать rowSums вместо sum.

Думаю этого должно хватить...

library(tidyverse)

# creating dataframe
df = data.frame(col1 = sample(c("YES","NO"),10,replace = T),
                col2 = sample(c("YES","NO"),10,replace = T),
                col3 = sample(c("YES","NO"),10,replace = T),
                col4 = sample(c("YES","NO"),10,replace = T),
                col5 = sample(c("YES","NO"),10,replace = T))


apply(df,2,function(x) as.numeric(x == "YES")) %>% # converting YES/NO to binary
  as.data.frame() %>% # changing from matrix to dataframe
  mutate(sum = rowSums(across(where(is.numeric)), na.rm = T)) # creating sum


#>    col1 col2 col3 col4 col5 sum
#> 1     1    0    0    1    0   2
#> 2     1    0    1    1    1   4
#> 3     0    0    0    0    1   1
#> 4     1    1    0    1    0   3
#> 5     0    0    1    0    0   1
#> 6     0    0    0    0    1   1
#> 7     0    1    0    1    0   2
#> 8     1    0    1    0    0   2
#> 9     1    1    0    1    0   3
#> 10    1    1    1    0    0   3

Или прямо это df %>% mutate(sum = rowSums(across(1:5, ~ .x == "YES"), na.rm = T))

Merijn van Tilborg 05.05.2022 14:52
Ответ принят как подходящий

Вы также можете использовать rowSums() непосредственно в операторе dplyr.

library(dplyr)

df %>% 
  mutate(x = rowSums(across(all_of(c("col1", "col2", "col3", "col4", "col5")), `==`, "YES")))

#      something col1 col2 col3 col4 col5 x
# 1  0.113703411   NO   NO  YES   NO   NO 1
# 2  0.622299405   NO   NO   NO  YES   NO 1
# 3  0.609274733   NO   NO  YES   NO   NO 1
# 4  0.623379442  YES   NO  YES   NO   NO 2
# 5  0.860915384   NO   NO  YES   NO  YES 2
# 6  0.640310605   NO   NO   NO  YES   NO 1
# 7  0.009495756   NO  YES  YES  YES  YES 4
# 8  0.232550506  YES   NO   NO  YES  YES 3
# 9  0.666083758   NO   NO   NO  YES   NO 1
# 10 0.514251141   NO   NO  YES   NO  YES 2

Вы также можете использовать помощники tidyselect в зависимости от того, как настроен ваш фрейм данных.

df %>% 
  mutate(x = rowSums(across(starts_with("col"), `==`, "YES")))

df %>% 
  mutate(x = rowSums(across(col1:col5, `==`, "YES")))

По поводу использования na.rm = TRUE. Я бы не стал этого делать. То, как обращаться с АН, требует более тщательного обдумывания. Не следует просто предполагать, что NA равно «НЕТ», не зная лучше вашей проблемы. Если это «НЕТ», то вместо этого я бы заменил это значение на каком-то этапе рабочего процесса.

Данные:

set.seed(1234)

df <- data.frame(something = runif (10),
                 col1 = sample(c("YES","NO"),10,replace = T),
                 col2 = sample(c("YES","NO"),10,replace = T),
                 col3 = sample(c("YES","NO"),10,replace = T),
                 col4 = sample(c("YES","NO"),10,replace = T),
                 col5 = sample(c("YES","NO"),10,replace = T))

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