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