I have a dataframe that I want to convert to a nested list with a custom level of nesting. This is how I do it, but I'm sure there is a better way:
data <- data.frame(city=c("A", "A", "B", "B"), street=c("a", "b", "a", "b"), tenant=c("Smith","Jones","Smith","Jones"), income=c(100,200,300,400))
nested_data <- lapply(levels(data$city), function(city){
data_city <- subset(data[data$city == city, ], select=-city)
list(city = city, street_values=lapply(levels(data_city$street), function(street){
data_city_street <- subset(data_city[data_city$street == street, ], select=-street)
tenant_values <- apply(data_city_street, 1, function(income_tenant){
income_tenant <- as.list(income_tenant)
list(tenant=income_tenant$tenant, income=income_tenant$income)
})
names(tenant_values) <- NULL
list(street=street, tenant_values=tenant_values)
}))
})
The output in JSON looks like:
library(rjson)
write(toJSON(nested_data), "")
[{"city":"A","street_values":[{"street":"a","tenant_values":[{"tenant":"Smith","income":"100"}]},{"street":"b","tenant_values":[{"tenant":"Jones","income":"200"}]}]},{"city":"B","street_values":[{"street":"a","tenant_values":[{"tenant":"Smith","income":"300"}]},{"street":"b","tenant_values":[{"tenant":"Jones","income":"400"}]}]}]
# or prettified:
[
{
"city": "A",
"street_values": [
{
"street": "a",
"tenant_values": [
{
"tenant": "Smith",
"income": "100"
}
]
},
{
"street": "b",
"tenant_values": [
{
"tenant": "Jones",
"income": "200"
}
]
}
]
},
{
"city": "B",
"street_values": [
{
"street": "a",
"tenant_values": [
{
"tenant": "Smith",
"income": "300"
}
]
},
{
"street": "b",
"tenant_values": [
{
"tenant": "Jones",
"income": "400"
}
]
}
]
}
]
Is there a better way to do this?
To convert Pandas DataFrame to List in Python, use the DataFrame. values(). tolist() function.
Grouped data framesdf %>% nest(data = c(x, y)) specifies the columns to be nested; i.e. the columns that will appear in the inner data frame. Alternatively, you can nest() a grouped data frame created by dplyr::group_by() . The grouping variables remain in the outer data frame and the others are nested.
What about using split
to get you most of the way, and rapply
for the last step:
nestedList <- rapply(lapply(split(data[-1], data[1]),
function(x) split(x[-1], x[1])),
f = function(x) as.character(unlist(x)),
how = "replace")
Here's the output:
nestedList
# $A
# $A$a
# $A$a$tenant
# [1] "Smith"
#
# $A$a$income
# [1] "100"
#
#
# $A$b
# $A$b$tenant
# [1] "Jones"
#
# $A$b$income
# [1] "200"
#
#
#
# $B
# $B$a
# $B$a$tenant
# [1] "Smith"
#
# $B$a$income
# [1] "300"
#
#
# $B$b
# $B$b$tenant
# [1] "Jones"
#
# $B$b$income
# [1] "400"
And the structure:
> str(nestedList)
List of 2
$ A:List of 2
..$ a:List of 2
.. ..$ tenant: chr "Smith"
.. ..$ income: chr "100"
..$ b:List of 2
.. ..$ tenant: chr "Jones"
.. ..$ income: chr "200"
$ B:List of 2
..$ a:List of 2
.. ..$ tenant: chr "Smith"
.. ..$ income: chr "300"
..$ b:List of 2
.. ..$ tenant: chr "Jones"
.. ..$ income: chr "400"
The structure doesn't exactly match what you're looking for, but this might help get you started with an alternative approach.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With