Find unique level of list of data set each column

Viewed 50

I have a list of 18 datasets, each dataset has some columns, how I write a loop to find the intersect by the index of column, and return list of index of column.


df1 <- data.frame(id = c(1:5), loc = c("a","b","c","a","b"))
df2 <- data.frame(id = c(3:7), ta = c("c","b","d","a","b"))
df3 <- data.frame(id = c(1:5), az = c("d","a","e","d","b"))

df <- list(df1, df2, df3)
df <- lapply(df, function(i) lapply(i, function(j) as.character(j)))

intersect(df[[1]][1], df[[2]][1], df[[3]][1])
intersect(df[[1]][2], df[[2]][2], df[[3]][2])

2 Answers

You may use Reduce on the intersect function and the [ in an sapply to choose sub list number.

Single:

Reduce(intersect, sapply(df, `[`, 1))
# [1] "3" "4" "5"
Reduce(intersect, sapply(df, `[`, 2))
# [1] "a" "b"

Or altogether:

lapply(1:2, function(i) Reduce(intersect, sapply(df, `[`, i)))
# [[1]]
# [1] "3" "4" "5"
# 
# [[2]]
# [1] "a" "b"

With tidyverse, we can use map/reduce

library(purrr)
library(dplyr)
map(df, pull, 1) %>% 
      reduce(intersect)
#[1] 3 4 5

Or as a function

f1 <- function(lstA, ind) {
          map(lstA, pull, ind) %>%
             reduce(intersect)
 }


f1(df, 1)
#[1] 3 4 5
f1(df, 2)
#[1] "a" "b"
          
Related