Your Data
Cleaned up dput:
dat <-
structure(list(ID = c("aaa", "bbb", "ccc", "ddd", "eee", "fff"),
lemon = c(NA, NA, NA, "lemon", "lemon", NA),
sprout = c(NA, "sprout", NA, "sprout", NA, NA),
lime = c(NA, NA, NA, "lime", "lime", NA),
apple = c("apple", NA, NA, NA, "apple", NA),
broccoli = c("broccoli", NA, "broccoli", NA, NA, NA),
grape = c("grape", NA, "grape", NA, "grape", NA),
meat = c(NA, NA, NA, NA, NA, "meat"),
FRUIT = c(NA, NA, NA, NA, NA, NA)),
class = "data.frame", row.names = c(NA, -6L))
Constants to identify your types of items
FRUITS <- c("apple", "grape", "lemon", "lime")
VEGGIE <- c("broccoli", "sprout")
MEAT <- c("meat")
Base R solution
This is a solution to exactly the question posed using base R. We use apply to go row by row for each set of items and count how many non missing items there are. Then we combine that information back into the FRUIT column so that it is TRUE if there are more than 1 fruit, FALSE if more than 1 veggies, and NA if there is more than one Meat, or if none of the prior statements were TRUE. In this setup, a row that has fruit and veggies and meat will still be TRUE. You can change the order of the ifelse statements if that is not the desired outcome.
fruit_rows <- apply(dat[FRUITS], 1, function(x) sum(!is.na(x)))
veggie_rows <- apply(dat[VEGGIE], 1, function(x) sum(!is.na(x)))
meat_rows <- apply(dat[MEAT], 1, function(x) sum(!is.na(x)))
dat$FRUIT = ifelse(fruit_rows > 0, TRUE,
ifelse(veggie_rows > 0, FALSE,
ifelse(meat_rows > 0, NA, NA)))
Tidy data
Your data would be easier to work with in a tidy format (see here). As it is, there's a lot of missing values and redundancies. Here's some code that re-organizes and cleans up the data.
First create a 'long' dataset that has multiple rows per id, with a record of each item they have.
library(tidyverse)
long <- dat %>% select(-FRUIT) %>%
pivot_longer(-ID, values_to = "item", values_drop_na = TRUE) %>%
select(-name)
Then, summarize for each id what item types they have. You can replace any with sum below if you want to know how many of each item type they have. From here, you can create your FRUIT column with an if_else statement pretty easily, similar to what was done in the section above.
items_by_id <- long %>% group_by(ID) %>%
summarize(hasFruit = any(item %in% FRUITS),
hasVeggie = any(item %in% VEGGIE),
hasMeat = any(item %in% MEAT))