stevec
stevec

Reputation: 52308

Convert a column of lists into a regular column in a data.frame?

Here is a data.frame where the second column is a column of lists (note there is also a NULL).

How can we convert each list into a regular element so the column is like any other character class column? (the NULL can be NA)

df <- structure(list(Year = c(2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 
2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 2013L, 
2014L, 2014L, 2014L, 2014L, 2014L), Country = list(Country = "Canada", 
    Country = "Germany", Country = "France", Country = "Germany", 
    Country = "Mexico", Country = "Germany", Country = "Germany", 
    Country = "Canada", NULL, Country = "Germany", Country = "Mexico", 
    Country = "Canada", Country = "Mexico", Country = "Germany", 
    Country = "Canada", Country = "United States of America", 
    Country = "Canada", Country = "Mexico", Country = "Canada", 
    Country = "Germany")), class = "data.frame", row.names = c(NA, 
-20L))

Note

df %>% sapply(class)
     Year   Country 
"integer"    "list" 

Desired result:

df %>% sapply(class)
     Year   Country 
"integer"    "character" 

Upvotes: 0

Views: 352

Answers (3)

Diego
Diego

Reputation: 422

Yet another way to keep it more aligned with dplyr's mutate.

  df2 = df %>% 
  mutate(NewCountry = if_else(
    sapply(df$Country, is.null), 
    "MISSING", 
    as.character(df$Country))
  )

> sapply(df2, class)
       Year     Country  NewCountry 
  "integer"      "list" "character" 

Upvotes: 1

s_baldur
s_baldur

Reputation: 33488

One option:

df$Country <- sapply(df$Country, function(x) if (length(x)) x else NA)

Another:

df$Country[lengths(df$Country) == 0] <- list(NA)
df$Country <- as.vector(df$Country)

Upvotes: 1

Duck
Duck

Reputation: 39595

I would suggest an approach using a function over your df data:

myfun <- function(x)
{
  if(is.null(x)) 
    {y <- NA} 
  else
  {
    y <- x[[1]]
  }
  return(y)
}
#Apply  
df$Newvar <- as.vector(do.call(rbind,lapply(df$Country,myfun)))

Output:

   Year                  Country                   Newvar
1  2014                   Canada                   Canada
2  2014                  Germany                  Germany
3  2014                   France                   France
4  2014                  Germany                  Germany
5  2014                   Mexico                   Mexico
6  2014                  Germany                  Germany
7  2014                  Germany                  Germany
8  2014                   Canada                   Canada
9  2014                     NULL                     <NA>
10 2014                  Germany                  Germany
11 2014                   Mexico                   Mexico
12 2014                   Canada                   Canada
13 2014                   Mexico                   Mexico
14 2014                  Germany                  Germany
15 2013                   Canada                   Canada
16 2014 United States of America United States of America
17 2014                   Canada                   Canada
18 2014                   Mexico                   Mexico
19 2014                   Canada                   Canada
20 2014                  Germany                  Germany

And some checks:

str(df)

'data.frame':   20 obs. of  3 variables:
 $ Year   : int  2014 2014 2014 2014 2014 2014 2014 2014 2014 2014 ...
 $ Country:List of 20
  ..$ Country: chr "Canada"
  ..$ Country: chr "Germany"
  ..$ Country: chr "France"
  ..$ Country: chr "Germany"
  ..$ Country: chr "Mexico"
  ..$ Country: chr "Germany"
  ..$ Country: chr "Germany"
  ..$ Country: chr "Canada"
  ..$        : NULL
  ..$ Country: chr "Germany"
  ..$ Country: chr "Mexico"
  ..$ Country: chr "Canada"
  ..$ Country: chr "Mexico"
  ..$ Country: chr "Germany"
  ..$ Country: chr "Canada"
  ..$ Country: chr "United States of America"
  ..$ Country: chr "Canada"
  ..$ Country: chr "Mexico"
  ..$ Country: chr "Canada"
  ..$ Country: chr "Germany"
 $ Newvar : chr  "Canada" "Germany" "France" "Germany" ...

Where Newvar is not a list now.

Upvotes: 1

Related Questions