0

I have this data:

data <- structure(list(client_id = c("A", "B", 
"C", "D", "E", "F"
)), row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"
))

Where I need to match it with this data_to_match:

data_to_match <- structure(list(client_id = c("A", "E", "F"
)), row.names = c(NA, -3L), class = c("tbl_df", "tbl", "data.frame"
))

Such as:

data[data$client_id %in% data_to_match,] # returns empty

I have tried without success (which are the solutions to various questions here):

as.list(data_to_match)
list(data_to_match)
unlist(as.list(data_to_match))

But If I create a list from scratch it works perfectly:

data_to_match_created_as_list <- c("A", "E", "F")
data[data$client_id %in% data_to_match_created_as_list,] # it returns the right rows

At the end, my question is, how do I transform the data_to_match to a list like data_to_match_created_as_list?

In addition, how is the right name for this different types of list? I looked up for how to transform vector or one-column dataframe to list and the solutions are not equal to a list created from scratch (as in the example above and my multiple tries)

caldwellst
  • 5,719
  • 6
  • 22
Chris
  • 2,019
  • 5
  • 22
  • 67
  • data_to_match_new<-data_to_match %>% unlist %>% unname() this is how I convert a 1 column dataframe to an unnamed vector – Joe Erinjeri Jan 26 '22 at 14:29
  • Your `data_to_match_created_as_list` is not a list, it's a vector. Would recommend reading up on data types in R, such as in [Advanced R](http://adv-r.had.co.nz/Data-structures.html). – caldwellst Jan 26 '22 at 14:32
  • Have a look at [joins](https://stackoverflow.com/questions/1299871/how-to-join-merge-data-frames-inner-outer-left-right), such as `dplyr::right_join(data, data_to_match, "client_id")` – Donald Seinen Jan 26 '22 at 14:38

3 Answers3

1

Why don't just using the name of the column (which will gives you a vector)?

data[data$client_id %in% data_to_match$client_id,]

or

data[data$client_id %in% data_to_match[[1]],]

Output:

# A tibble: 3 × 1
  client_id
  <chr>    
1 A        
2 E        
3 F     

Check:

data[data$client_id %in% data_to_match$client_id,] == data[data$client_id %in% data_to_match_created_as_list,]

     client_id
[1,]      TRUE
[2,]      TRUE
[3,]      TRUE
Marco_CH
  • 3,243
  • 8
  • 25
1

While @Marco_CH answers works perfectly, if you just want an answer to the question:

At the end, my question is, how do I transform the data_to_match to a list like data_to_match_created_as_list?

Applying arrays to the unlisted initial data to match will work:

array(unlist(data_to_match))
# [1] "A" "E" "F"
data[data$client_id %in% array(unlist(data_to_match)),]
# [1] "A" "E" "F"
DjibSA
  • 161
  • 1
  • 6
  • Great solution (*upvote*). There is just one risk, if the data.frame gets two columns, isn't it? Than I think the second column will also be appended in the vector? – Marco_CH Jan 26 '22 at 15:03
  • 1
    @Marco_CH Yes indeed, but the question title is: R - How to transform a **one-column dataframe** to a ¿real? list. But sure, in a more general case, one should be careful, as you said, other columns would be appended. – DjibSA Jan 26 '22 at 15:16
  • You're right. Thanks – Marco_CH Jan 26 '22 at 15:19
1

This question could be approached in different ways, depending on how many common columns the data have, what their structure is and what the expected output should look like.

If you want a vector

Reduce(intersect, c(data, data_to_match))
#> [1] "A" "E" "F"

unlist(c(data, data_to_match), use.names = F) |>
  (\(.) .[duplicated(.)])()

a tibble

dplyr::right_join(data, data_to_match, "client_id")
# A tibble: 3 x 1
  client_id
  <chr>    
1 A        
2 E        
3 F 

or matrix

mapply(intersect, data, data_to_match)
     client_id
[1,] "A"      
[2,] "E"      
[3,] "F" 
Donald Seinen
  • 4,179
  • 5
  • 15
  • 40