使用函数从不同级别的列表中提取数据
Extracting data from lists of different levels using a function
大家早上好。
我有一个函数,它使用列表作为参数,通过将元素提取到 df 中来生成不同的指标。但是,我打算使用的列表具有不同的层级,因此我不能对所有列表都使用它。
我在下面给出一个例子(不是真正的函数):
# the function pulls out a df from a list
df_func <- function(list){
df_temp <- list[[1]]
return(df_temp)
}
data("iris")
list_a <- list("list_a" = iris, "list_b" = iris,
"list_c" = iris, "list_d" = iris)
list_b <- list()
list_b[["list_a"]] <- list_a
list_b[["list_b"]] <- list_a
list_b[["list_c"]] <- list_a
list_b[["list_d"]] <- list_a
df1 <- df_func(list_a) # correct (returns a df)
df2 <- df_func(list_b) # wrong (returns a list of dfs)
我知道问题在于,要从 list_a
访问正确的元素,我们使用 list_a[[1]]
而要从 list_b
中提取正确的元素,我们必须使用list_b[[1]][[1]]
.
我的问题是如何在函数中对此进行编码,以便 R 知道在哪里寻找我需要的 df?
感谢大家对新手的帮助。
如果您有一个列表列表(嵌套列表),您可以在函数中指定第二个参数(以及第三个、第四个等)以在嵌套列表中使用。
df_func <- function(list, list2, index = 1){
df_temp <- list[[list2]][[index]] # default index = 1
return(df_temp)
}
df_func(list_b, 1) # outputs `list_b[[1]][[1]]`
df_func(list_b, 2) # outputs `list_b[[2]][[1]]`
df_func(list_b, 2, 2) # outputs `list_b[[2]][[2]]`
它不适用于list_a
,因为它不是嵌套列表(也不是同级嵌套列表)。对于更高级别的嵌套列表,您还需要更多参数。
这里有一个更高级的方法,不受任何特定嵌套级别的限制:
df_func2 <- function(list, index = 1) {
l <- paste0("[[",index,"]]", collapse="")
l2 <- paste0(deparse(substitute(list)),l)
df_temp <- eval(parse(text=l2))
return(df_temp)
}
df_func2(list_a) # outputs `list_a[[1]]`
df_func2(list_a, 2) # outputs `list_a[[2]]`
df_func2(list_b, 1) # outputs `list_b[[1]]` (list of data frames)
df_func2(list_b, c(1, 1)) # outputs `list_b[[1]][[1]]`
df_func2(list_b, c(1, 2)) # outputs `list_b[[1]][[2]]`
使用递归函数怎么样?
df_func <- function(list){
tmp <- list[[1]]
if(class(tmp) == 'list') {
df_func(tmp)
} else tmp
}
考虑使用已经可用的递归函数,即 rapply/rrapply
df_func <- function(listObj) {
rrapply::rrapply(listObj, classes = "data.frame", how = 'flatten')[[1]]
}
-测试
> out1 <- df_func(list_a)
> out2 <- df_func(list_b)
> str(out1)
'data.frame': 150 obs. of 5 variables:
$ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
$ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
$ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
$ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
$ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
> str(out2)
'data.frame': 150 obs. of 5 variables:
$ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
$ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
$ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
$ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
$ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
大家早上好。
我有一个函数,它使用列表作为参数,通过将元素提取到 df 中来生成不同的指标。但是,我打算使用的列表具有不同的层级,因此我不能对所有列表都使用它。
我在下面给出一个例子(不是真正的函数):
# the function pulls out a df from a list
df_func <- function(list){
df_temp <- list[[1]]
return(df_temp)
}
data("iris")
list_a <- list("list_a" = iris, "list_b" = iris,
"list_c" = iris, "list_d" = iris)
list_b <- list()
list_b[["list_a"]] <- list_a
list_b[["list_b"]] <- list_a
list_b[["list_c"]] <- list_a
list_b[["list_d"]] <- list_a
df1 <- df_func(list_a) # correct (returns a df)
df2 <- df_func(list_b) # wrong (returns a list of dfs)
我知道问题在于,要从 list_a
访问正确的元素,我们使用 list_a[[1]]
而要从 list_b
中提取正确的元素,我们必须使用list_b[[1]][[1]]
.
我的问题是如何在函数中对此进行编码,以便 R 知道在哪里寻找我需要的 df?
感谢大家对新手的帮助。
如果您有一个列表列表(嵌套列表),您可以在函数中指定第二个参数(以及第三个、第四个等)以在嵌套列表中使用。
df_func <- function(list, list2, index = 1){
df_temp <- list[[list2]][[index]] # default index = 1
return(df_temp)
}
df_func(list_b, 1) # outputs `list_b[[1]][[1]]`
df_func(list_b, 2) # outputs `list_b[[2]][[1]]`
df_func(list_b, 2, 2) # outputs `list_b[[2]][[2]]`
它不适用于list_a
,因为它不是嵌套列表(也不是同级嵌套列表)。对于更高级别的嵌套列表,您还需要更多参数。
这里有一个更高级的方法,不受任何特定嵌套级别的限制:
df_func2 <- function(list, index = 1) {
l <- paste0("[[",index,"]]", collapse="")
l2 <- paste0(deparse(substitute(list)),l)
df_temp <- eval(parse(text=l2))
return(df_temp)
}
df_func2(list_a) # outputs `list_a[[1]]`
df_func2(list_a, 2) # outputs `list_a[[2]]`
df_func2(list_b, 1) # outputs `list_b[[1]]` (list of data frames)
df_func2(list_b, c(1, 1)) # outputs `list_b[[1]][[1]]`
df_func2(list_b, c(1, 2)) # outputs `list_b[[1]][[2]]`
使用递归函数怎么样?
df_func <- function(list){
tmp <- list[[1]]
if(class(tmp) == 'list') {
df_func(tmp)
} else tmp
}
考虑使用已经可用的递归函数,即 rapply/rrapply
df_func <- function(listObj) {
rrapply::rrapply(listObj, classes = "data.frame", how = 'flatten')[[1]]
}
-测试
> out1 <- df_func(list_a)
> out2 <- df_func(list_b)
> str(out1)
'data.frame': 150 obs. of 5 variables:
$ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
$ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
$ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
$ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
$ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
> str(out2)
'data.frame': 150 obs. of 5 variables:
$ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
$ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
$ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
$ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
$ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...