我有未知结构(嵌套)的列表,它总是以命名向量终止。我想用列表中的所有句点或原子向量名替换下划线。有rapply
将functios应用于列表元素,但如何应用列表/原子向量的名称?我是基于R的解决方案,但请为其他人分享所有解决方案。
x <- list(
urban = list(
cars = c('volvo', 'ford'),
food.dining = list(
local.business = c('carls'),
chain.business = c('dennys', 'panera')
)
),
rural = list(
land.use = list(
farming =list(
dairy = c('cows'),
vegie.plan = c('carrots')
)
),
social.rec = list(
community.center = c('town.square')
),
people.type = c('good', 'bad', 'in.between')
),
other.locales = c('suburban'),
missing = list(
unknown = c(),
known = c()
),
end = c('wow')
)
## $urban
## $urban$cars
## [1] "volvo" "ford"
##
## $urban$food_dining
## $urban$food_dining$local_business
## [1] "carls"
##
## $urban$food_dining$chain_business
## [1] "dennys" "panera"
##
##
##
## $rural
## $rural$land_use
## $rural$land_use$farming
## $rural$land_use$farming$dairy
## [1] "cows"
##
## $rural$land_use$farming$vegie_plan
## [1] "carrots"
##
##
##
## $rural$social_rec
## $rural$social_rec$community_center
## [1] "town.square"
##
##
## $rural$people_type
## [1] "good" "bad" "in.between"
##
##
## $other_locales
## [1] "suburban"
##
## $missing
## $missing$unknown
## NULL
##
## $missing$known
## NULL
##
##
## $end
## [1] "wow"
答案 0 :(得分:5)
这是一个递归函数的想法。它首先用下划线替换名称中的句点。然后检查元素的类是否为list
,如果是,则将该函数应用于该元素。否则,如果类为character
,则它将元素中的句点替换为下划线。请注意,如果列表中有data.frames
,那么这将不起作用,它必须是函数中定义的扩展名。希望这有帮助!
功能:
my_func <- function(x)
{
names(x) <- gsub('\\.','_',names(x) )
for(i in 1:length(x))
{
if(any(class(x[[i]])=='list'))
{
x[[i]] <- my_func(x[[i]])
}
}
return(x)
}
y <- my_func(x)
数据:
x <- list(
urban = list(
cars = c('volvo', 'ford'),
food.dining = list(
local.business = c('carls'),
chain.business = c('dennys', 'panera')
)
),
rural = list(
land.use = list(
farming =list(
dairy = c('cows'),
vegie.plan = c('carrots')
)
),
social.rec = list(
community.center = c('town.square')
),
people.type = c('good', 'bad', 'in.between')
),
other.locales = c('suburban'),
missing = list(
unknown = c(),
known = c()
),
end = c('wow')
)
输出:
str(y)
List of 5
$ urban :List of 2
..$ cars : chr [1:2] "volvo" "ford"
..$ food_dining:List of 2
.. ..$ local_business: chr "carls"
.. ..$ chain_business: chr [1:2] "dennys" "panera"
$ rural :List of 3
..$ land_use :List of 1
.. ..$ farming:List of 2
.. .. ..$ dairy : chr "cows"
.. .. ..$ vegie_plan: chr "carrots"
..$ social_rec :List of 1
.. ..$ community_center: chr "town.square"
..$ people_type: chr [1:3] "good" "bad" "in.between"
$ other_locales: chr "suburban"
$ missing :List of 2
..$ unknown: NULL
..$ known : NULL
$ end : chr "wow"
答案 1 :(得分:4)
对于list
个对象,它将重命名list
并递归地为每个元素调用相同的函数。对于character
个对象,它只会返回character
。
library('purrr')
fix_names.list <- function(v) {
names(v) <- gsub('\\.', '_', names(v))
map(v, fix_names)
}
fix_names.default <- function(v) v
fix_names <- function(v) UseMethod('fix_names')
fix_names(x) %>% str
# List of 5
# $ urban :List of 2
# ..$ cars : chr [1:2] "volvo" "ford"
# ..$ food_dining:List of 2
# .. ..$ local_business: chr "carls"
# .. ..$ chain_business: chr [1:2] "dennys" "panera"
# $ rural :List of 3
# ..$ land_use :List of 1
# .. ..$ farming:List of 2
# .. .. ..$ dairy : chr "cows"
# .. .. ..$ vegie_plan: chr "carrots"
# ..$ social_rec :List of 1
# .. ..$ community_center: chr "town.square"
# ..$ people_type: chr [1:3] "good" "bad" "in.between"
# $ other_locales: chr "suburban"
# $ missing :List of 2
# ..$ unknown: NULL
# ..$ known : NULL
# $ end : chr "wow"
答案 2 :(得分:1)
这不是base-R的方法,但可能仍然很重要,因为可以使用rrapply
包中的rrapply
开箱即用(base-{{的扩展名) 1}}):
rapply
将library(rrapply)
res1 <- rrapply(list(x),
f = function(x) { names(x) <- gsub("\\.", "_", names(x)); x },
classes = "list",
how = "recurse")[[1]]
str(res1)
#> List of 5
#> $ urban :List of 2
#> ..$ cars : chr [1:2] "volvo" "ford"
#> ..$ food_dining:List of 2
#> .. ..$ local_business: chr "carls"
#> .. ..$ chain_business: chr [1:2] "dennys" "panera"
#> $ rural :List of 3
#> ..$ land_use :List of 1
#> .. ..$ farming:List of 2
#> .. .. ..$ dairy : chr "cows"
#> .. .. ..$ vegie_plan: chr "carrots"
#> ..$ social_rec :List of 1
#> .. ..$ community_center: chr "town.square"
#> ..$ people_type: chr [1:3] "good" "bad" "in.between"
#> $ other_locales: chr "suburban"
#> $ missing :List of 2
#> ..$ unknown: NULL
#> ..$ known : NULL
#> $ end : chr "wow"
应用到类型how = "recurse"
的每个元素后, f
继续递归。在这里,我将输入对象包装为classes = "list"
,以便也在顶部列表层应用list(x)
函数,而不是从其列表元素开始。
注意:我们可以轻松地更新调用以在名称和嵌套列表的值中组合替换:
f