user2006697
user2006697

Reputation: 1117

Function to select value from data frame based on value in list of lists

In R I need to write a function that applies the following rules:

fkt <- function(v1,v2){
    - find list name within listOfLists that contains v1       
    - go to column in df, where listname == colname  
    - return value from row where df$col2 == v2

}

For Example:

df <- data.frame(Col1= c(1,2,3,4,5),
                   Col2= c("AAA","BBB","CCC","DDD","EEE"),
                   A = c("22","22","23","23","24"),
                   B = c("210","210","202","220","203"),
                   C = c("2000","2000","2010","2010","2200")
                   )



listOflists <- list(A <- c(1281, 1282, 1285, 1286, 1289),
                    B <- c(100,200,300,400,500,600,700,800,900,101,202,303,404,505,606),
                    C <-c(1000,1500,2000,2500,3000,3050,4000,4500,6000)
)

Then

fkt(800,"BBB") 
> 210

I tried

fkt<- function(v1,v2){
      r <- which(df$Col2== v1)
      s <- ifelse(v2 %in% A, df$A[r], 
                 ifelse( v2 %in% B ,df$A[r],df$C[r]))
  return(s)
}

Alas, the result is NA. And writing many ifelse() statements is not efficient - especially because the listOfLists might comprise >50 lists.

Can anyone advice me how to write this function in a general, programming efficient way as described above?

Upvotes: 1

Views: 115

Answers (1)

Nicolas2
Nicolas2

Reputation: 2210

df <- data.frame(Col1= c(1,2,3,4,5),
               Col2= c("AAA","BBB","CCC","DDD","EEE"),
               A = c("22","22","23","23","24"),
               B = c("210","210","202","220","203"),
               C = c("2000","2000","2010","2010","2200"))
# Be cautious : = and <- are not equivalent, you were creating variables not named fields
listOflists <- list(A = c(1281, 1282, 1285, 1286, 1289),
                    B = c(100,200,300,400,500,600,700,800,900,101,202,303,404,505,606),
                    C = c(1000,1500,2000,2500,3000,3050,4000,4500,6000))

f <- function(v1) 
  for (i in 1:length(listOflists)) 
    if (v1 %in% listOflists[[i]]) return(names(listOflists)[i])

fkt <- function(v1,v2) df[df$Col2==v2,f(v1)]

fkt(800,"BBB")
#[1] 210
#Levels: 202 203 210 220

Upvotes: 2

Related Questions