How to find if ANY column has a specific value I am looking for?

后端 未结 5 601
我在风中等你
我在风中等你 2021-01-18 20:56
   id first  middle  last       Age
    1 Carol  Jenny   Smith      15
    2 Sarah  Carol   Roberts    20
    3 Josh   David   Richardson 22

I am t

5条回答
  •  温柔的废话
    2021-01-18 21:29

    Using tidyverse

    library(tidyverse)
    f1 <- function(data, wordToCompare, colsToCompare) {
              wordToCompare <- enquo(wordToCompare)
              data %>%
                  select(colsToCompare) %>%
                  mutate(!! wordToCompare :=  map(.,  ~ 
           .x == as_label(wordToCompare)) %>% 
               reduce(`|`) %>%
               as.integer)
                  }
              
    f1(df1, Carol, c("first", 'middle', 'last'))
    # first middle       last Carol
    #1 Carol  Jenny      Smith     1
    #2 Sarah  Carol    Roberts     1
    #3  Josh  David Richardson     0
    
    f1(df1, Sarah, c("first", 'middle', 'last'))
    #   first middle       last Sarah
    #1 Carol  Jenny      Smith     0
    #2 Sarah  Carol    Roberts     1
    #3  Josh  David Richardson     0
    

    Or this can also be done with pmap

    df1 %>%
      mutate(Carol = pmap_int(.[c('first', 'middle', 'last')],
              ~ +('Carol' %in% c(...))))
    #   id first middle       last Age Carol
    #1  1 Carol  Jenny      Smith  15     1
    #2  2 Sarah  Carol    Roberts  20     1
    #3  3  Josh  David Richardson  22     0
    

    which can be wrapped into a function

    f2 <- function(data, wordToCompare, colsToCompare) {
          wordToCompare <- enquo(wordToCompare)
          data %>%
               mutate(!! wordToCompare := pmap_int(.[colsToCompare],
              ~ +(as_label(wordToCompare) %in% c(...))))
      } 
    
    f2(df1, Carol, c("first", 'middle', 'last'))
    #  id first middle       last Age Carol
    #1  1 Carol  Jenny      Smith  15     1
    #2  2 Sarah  Carol    Roberts  20     1
    #3  3  Josh  David Richardson  22     0
    

    NOTE: Both the tidyverse methods doesn't require any reshaping


    With base R, we can loop through the 'first', 'middle', 'last' column and use == for comparison to get a list of logical vectors, which we Reduce to a single logical vector with | and coerce it to binary with +

    df1$Carol <- +(Reduce(`|`, lapply(df1[2:4], `==`, 'Carol')))
    df1
    #  id first middle       last Age Carol
    #1  1 Carol  Jenny      Smith  15     1
    #2  2 Sarah  Carol    Roberts  20     1 
    #3  3  Josh  David Richardson  22     0
    

    NOTE: There are dupes for this post. For e.g. here

    data

    df1 <- structure(list(id = 1:3, first = c("Carol", "Sarah", "Josh"), 
    middle = c("Jenny", "Carol", "David"), last = c("Smith", 
    "Roberts", "Richardson"), Age = c(15L, 20L, 22L)),
      class = "data.frame", row.names = c(NA, 
     -3L))
    
              
       
    

提交回复
热议问题