Преобразовать столбец списков в обычный столбец в data.frame?

#r #lapply #purrr #sapply

#r #lapply #мурлыканье #sapply

Вопрос:

Вот data.frame, где второй столбец является столбцом списков (обратите внимание, что там также есть NULL ).

Как мы можем преобразовать каждый список в обычный элемент, чтобы столбец был похож на любой другой столбец символьного класса? ( NULL может быть 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))
  

Примечание

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

Желаемый результат:

  • Те же данные, но
 df %>% sapply(class)
     Year   Country 
"integer"    "character" 
  

Ответ №1:

Я бы предложил подход с использованием функции над вашими df данными:

 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)))
  

Вывод:

    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
  

И некоторые проверки:

 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" ...
  

Где Newvar теперь нет списка.

Ответ №2:

Один из вариантов:

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

Другой:

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

Ответ №3:

Еще один способ привести его в соответствие с dplyr 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"