Проверьте, существует ли одно значение в строке, все столбцы объединены в R

#r

#r

Вопрос:

Я хочу создать фрейм данных, в котором есть 5 столбцов (Ball1, Ball2, Ball3, Ball4 и Ball5), и каждый столбец может принимать любое из 3 значений (Box1, Box2, Box3). Код для генерации фрейма данных приведен ниже:

 iterations = 10
variables = 5

output <- matrix(ncol=variables, nrow=iterations)

for(i in 1:iterations){
  output[i,] <- sample(c("Box1","Box2","Box3"), 5, replace=T)
  
}
output <- data.frame(output)
colnames(output)[1] <- "Ball1"
colnames(output)[2] <- "Ball2"
colnames(output)[3] <- "Ball3"
colnames(output)[4] <- "Ball4"
colnames(output)[5] <- "Ball5"
output
  

Теперь я хочу создать 6-й столбец «All_Boxes_Present», где я хочу посмотреть, присутствуют ли для конкретной строки все поля хотя бы один раз. Если присутствует, то 6-й столбец должен быть равен 1, иначе 0.
Ниже приведен пример вывода:

Ожидаемая выходная таблица

Выходная таблица

Ответ №1:

Мы можем использовать apply в базе R, чтобы проверить, all присутствуют ли поля в каждой строке, и присвоить 1/0 соответственно.

 all_boxes <- c("Box1","Box2","Box3")
output$all_present <-  (apply(output, 1, function(x) all(all_boxes %in% x)))
  

В dplyr мы можем сделать это с rowwise :

 library(dplyr)

output %>%
  rowwise() %>%
  mutate(all_box_present =  (all(all_boxes %in% c_across())))

# Ball1 Ball2 Ball3 Ball4 Ball5 all_box_present
#   <chr> <chr> <chr> <chr> <chr>           <int>
# 1 Box2  Box2  Box1  Box2  Box1                0
# 2 Box1  Box2  Box3  Box1  Box3                1
# 3 Box1  Box2  Box1  Box2  Box2                0
# 4 Box2  Box3  Box1  Box1  Box1                1
# 5 Box1  Box3  Box1  Box2  Box1                1
# 6 Box2  Box2  Box1  Box1  Box1                0
# 7 Box1  Box3  Box1  Box1  Box1                0
# 8 Box2  Box2  Box3  Box2  Box3                0
# 9 Box1  Box1  Box1  Box1  Box1                0
#10 Box3  Box1  Box1  Box3  Box3                0
  

в начале изменяет логические значения ( TRUE / FALSE ) на целые числа ( 1 / 0 ) соответственно.

Ответ №2:

Мы можем использовать векторную опцию с Reduce в base R

 output$all_present <-  (Reduce(`amp;`, lapply(all_boxes, function(x)
              rowSums(output == x) > 0)))
  

Или мы можем использовать tidyverse

 library(dplyr)
library(purrr)
output %>% 
   mutate(all_present = map(all_boxes, function(x) rowSums(x == .) %>%
         magrittr::is_greater_than(0)) %>%
         reduce(`amp;`) %>% as.integer)
  

данные

 all_boxes <- c("Box1","Box2","Box3")