我如何做一个数据帧的列表,我如何从列表中访问每个这些数据帧?
例如,如何将这些数据帧放入列表中?
d1 <- data.frame(y1 = c(1, 2, 3),
y2 = c(4, 5, 6))
d2 <- data.frame(y1 = c(3, 2, 1),
y2 = c(6, 5, 4))
我如何做一个数据帧的列表,我如何从列表中访问每个这些数据帧?
例如,如何将这些数据帧放入列表中?
d1 <- data.frame(y1 = c(1, 2, 3),
y2 = c(4, 5, 6))
d2 <- data.frame(y1 = c(3, 2, 1),
y2 = c(6, 5, 4))
当前回答
对于循环模拟
如果我有一个生成数据框架的for循环,我从一个空list()开始,并在生成数据框架时附加数据框架。
# Empty list
dat_list <- list()
for(i in 1:5){
# Generate dataframe
dat <- data.frame(x=rnorm(10), y=rnorm(10))
# Add to list
dat_list <- append(dat_list, list(dat))
}
注意,它是在append()调用中的list(dat)。
访问数据
然后使用dat_list[[n]]从列表中获取第n个数据帧。你可以通过正常的方式访问这个数据帧中的数据,例如dat_list[[2]]$x。
或者,如果你想从所有的数据框架中获得相同的部分,则使用(dat_list, "[", "x")。
见@Gregor Thomas的回答,没有for循环。
其他回答
在tidyverse中,可以使用函数lst()根据对象自动命名列表。
library(tibble)
d1 <- data.frame(y1 = c(1, 2, 3),
y2 = c(4, 5, 6))
d2 <- data.frame(y1 = c(3, 2, 1),
y2 = c(6, 5, 4))
lst(d1, d2)
# $d1
# y1 y2
# 1 1 4
# 2 2 5
# 3 3 6
#
# $d2
# y1 y2
# 1 3 6
# 2 2 5
# 3 1 4
在编译稍后要按名称引用的列表时,这可能很有帮助。
如果你有大量按顺序命名的数据帧,你可以像这样创建一个所需数据帧子集的列表:
d1 <- data.frame(y1=c(1,2,3), y2=c(4,5,6))
d2 <- data.frame(y1=c(3,2,1), y2=c(6,5,4))
d3 <- data.frame(y1=c(6,5,4), y2=c(3,2,1))
d4 <- data.frame(y1=c(9,9,9), y2=c(8,8,8))
my.list <- list(d1, d2, d3, d4)
my.list
my.list2 <- lapply(paste('d', seq(2,4,1), sep=''), get)
my.list2
我的地方。List2返回一个包含第2、3和4个数据帧的列表。
[[1]]
y1 y2
1 3 6
2 2 5
3 1 4
[[2]]
y1 y2
1 6 3
2 5 2
3 4 1
[[3]]
y1 y2
1 9 8
2 9 8
3 9 8
但是请注意,上面列表中的数据帧不再被命名。如果你想创建一个包含数据帧子集的列表,并且想要保留它们的名称,你可以尝试这样做:
list.function <- function() {
d1 <- data.frame(y1=c(1,2,3), y2=c(4,5,6))
d2 <- data.frame(y1=c(3,2,1), y2=c(6,5,4))
d3 <- data.frame(y1=c(6,5,4), y2=c(3,2,1))
d4 <- data.frame(y1=c(9,9,9), y2=c(8,8,8))
sapply(paste('d', seq(2,4,1), sep=''), get, environment(), simplify = FALSE)
}
my.list3 <- list.function()
my.list3
返回:
> my.list3
$d2
y1 y2
1 3 6
2 2 5
3 1 4
$d3
y1 y2
1 6 3
2 5 2
3 4 1
$d4
y1 y2
1 9 8
2 9 8
3 9 8
> str(my.list3)
List of 3
$ d2:'data.frame': 3 obs. of 2 variables:
..$ y1: num [1:3] 3 2 1
..$ y2: num [1:3] 6 5 4
$ d3:'data.frame': 3 obs. of 2 variables:
..$ y1: num [1:3] 6 5 4
..$ y2: num [1:3] 3 2 1
$ d4:'data.frame': 3 obs. of 2 variables:
..$ y1: num [1:3] 9 9 9
..$ y2: num [1:3] 8 8 8
> my.list3[[1]]
y1 y2
1 3 6
2 2 5
3 1 4
> my.list3$d4
y1 y2
1 9 8
2 9 8
3 9 8
假设你有“大量”名称相似的data.frames(这里的d#是一个正整数),下面的方法是对@mark-miller方法的轻微改进。它更简洁,返回data.frames的命名列表,其中列表中的每个名称都是对应的原始data.frame的名称。
关键是使用mget和ls。如果问题中提供的数据帧d1和d2是环境中仅有的名称为d#的对象,那么
my.list <- mget(ls(pattern="^d[0-9]+"))
它会返回
my.list
$d1
y1 y2
1 1 4
2 2 5
3 3 6
$d2
y1 y2
1 3 6
2 2 5
3 1 4
这个方法利用了ls中的pattern参数,它允许我们使用正则表达式对环境中对象的名称进行更精细的解析。另一个正则表达式”^ d[0 - 9] + $”是“^ \ \ d +美元”。
正如@gregor指出的那样,从整体上讲,更好的方法是设置数据构建过程,以便在开始时将data.frames放入命名列表中。
data
d1 <- data.frame(y1 = c(1,2,3),y2 = c(4,5,6))
d2 <- data.frame(y1 = c(3,2,1),y2 = c(6,5,4))
我认为自己是一个完全的新手,但我认为对于这里没有陈述的原始子问题之一,我有一个极其简单的答案:访问数据帧或数据帧的一部分。
让我们首先创建上面所述的数据帧列表:
d1 <- data.frame(y1 = c(1, 2, 3), y2 = c(4, 5, 6))
d2 <- data.frame(y1 = c(3, 2, 1), y2 = c(6, 5, 4))
my.list <- list(d1, d2)
然后,如果希望访问其中一个数据帧中的特定值,可以按顺序使用双括号。第一组让你进入数据帧,第二组让你到达特定的坐标:
my.list[[1]][3, 2]
[1] 6
这与您的问题无关,但您希望在函数调用中使用=而不是<-。如果你使用<-,你最终会在你工作的环境中创建变量y1和y2:
d1 <- data.frame(y1 <- c(1, 2, 3), y2 <- c(4, 5, 6))
y1
# [1] 1 2 3
y2
# [1] 4 5 6
这似乎没有在数据帧中创建列名的理想效果:
d1
# y1....c.1..2..3. y2....c.4..5..6.
# 1 1 4
# 2 2 5
# 3 3 6
另一方面,=操作符将你的向量与data.frame的参数关联起来。
至于你的问题,做一个数据帧列表很简单:
d1 <- data.frame(y1 = c(1, 2, 3), y2 = c(4, 5, 6))
d2 <- data.frame(y1 = c(3, 2, 1), y2 = c(6, 5, 4))
my.list <- list(d1, d2)
访问数据帧就像访问任何其他列表元素一样:
my.list[[1]]
# y1 y2
# 1 1 4
# 2 2 5
# 3 3 6