我如何做一个数据帧的列表,我如何从列表中访问每个这些数据帧?

例如,如何将这些数据帧放入列表中?

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))

当前回答

假设你有“大量”名称相似的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

还可以使用[和[[]访问每个列表元素中的特定列和值。这里有几个例子。首先,使用lapply(ldf, "[", 1)只能访问列表中每个数据帧的第一列,其中1表示列号。

ldf <- list(d1 = d1, d2 = d2)  ## create a named list of your data frames
lapply(ldf, "[", 1)
# $d1
#   y1
# 1  1
# 2  2
# 3  3
#
# $d2
#   y1
# 1  3
# 2  2
# 3  1

类似地,我们可以访问第二列中的第一个值

lapply(ldf, "[", 1, 2)
# $d1
# [1] 4
# 
# $d2
# [1] 6

然后我们还可以直接访问列值,作为一个向量,使用[[

lapply(ldf, "[[", 1)
# $d1
# [1] 1 2 3
#
# $d2
# [1] 3 2 1

非常简单!以下是我的建议:

如果你想在你的工作空间中选择数据框架,试试这个:

Filter(function(x) is.data.frame(get(x)) , ls())

or

ls()[sapply(ls(), function(x) is.data.frame(get(x)))]

所有这些都会得到相同的结果。

你可以改变is.data.frame来检查其他类型的变量,比如is.function

对于循环模拟

如果我有一个生成数据框架的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循环。