Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elements within lists.

Tags:

list

r

I'm relatively new in R (~3 months), and so I'm just getting the hang of all the different data types. While lists are a super useful way of holding dissimilar data all in one place, they are also extremely inflexible for function calls, and riddle me with angst.

For the work I'm doing, I often uses lists because I need to hold a bunch of vectors of different lengths. For example, I'm tracking performance statistics of about 10,000 different vehicles, and there are certain vehicles which are so similar they can essentially be treated as the same vehicles for certain analyses.

So let's say we have this list of vehicle ID's:

List <- list(a=1, b=c(2,3,4), c=5)

For simplicity's sake.

I want to do two things:

  1. Tell me which element of a list a particular vehicle is in. So when I tell R I'm working with vehicle 2, it should tell me b or [2]. I feel like it should be something simple like how you can do

    match(3,b)
    > 2
    
  2. Convert it into a data frame or something similar so that it can be saved as a CSV. Unused rows could be blank or NA. What I've had to do so far is:

    for(i in length(List)) {
    length(List[[i]]) <- max(as.numeric(as.matrix(summary(List)[,1])))
    }
    DF <- as.data.frame(List)
    

Which seems dumb.

like image 722
Señor O Avatar asked Feb 18 '23 17:02

Señor O


2 Answers

For your first question:

which(sapply(List, `%in%`, x = 3))
# b 
# 2 

For your second question, you could use a function like this one:

list.to.df <- function(arg.list) {
   max.len  <- max(sapply(arg.list, length))
   arg.list <- lapply(arg.list, `length<-`, max.len)
   as.data.frame(arg.list)
}
list.to.df(List)
#    a b  c
# 1  1 2  5
# 2 NA 3 NA
# 3 NA 4 NA
like image 65
flodel Avatar answered Feb 22 '23 00:02

flodel


Both of those tasks (and many others) would become much easier if you were to "flatten" your data into a data.frame. Here's one way to do that:

fun <- function(X) 
    data.frame(element = X, vehicle = List[[X]], stringsAsFactors = FALSE)
df <- do.call(rbind, lapply(names(List), fun))
#   element vehicle
# 1       a       1
# 2       b       2
# 3       b       3
# 4       b       4
# 5       c       5

With a data.frame in hand, here's how you could perform your two tasks:

## Task #1
with(df, element[match(3, vehicle)])
# [1] "b"

## Task #2
write.csv(df, file = "outfile.csv")
like image 45
Josh O'Brien Avatar answered Feb 22 '23 00:02

Josh O'Brien