Reputation: 52308
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
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
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
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