循环遍历数据框和变量名
Posted
技术标签:
【中文标题】循环遍历数据框和变量名【英文标题】:Loop through data frame and variable names 【发布时间】:2013-05-18 19:38:30 【问题描述】:我正在寻找一种使用 FOR 循环在 R 中自动化某些图表的方法:
dflist <- c("dataframe1", "dataframe2", "dataframe3", "dataframe4")
for (i in dflist)
plot(i$var1, i$var2)
所有数据帧都具有相同的变量,即 var1、var2。
似乎for
循环不是这里最优雅的解决方案,但我不明白如何将apply
函数用于图表。
编辑:
我使用mean()
的原始示例对原始问题没有帮助,因此我将其更改为绘图函数。
【问题讨论】:
使用for
循环很好。只需将实际的 data.frames 放在一个列表中,而不仅仅是将它们的名称放在一个向量中。为了更具可读性,您还可以将循环内容更改为plot(var2~var1, data=i)
。但是,您可能想要保存图表(阅读?pdf
)或将多个图表放在一个图形页面上(阅读?par
)。
虽然我同意 Roland 的观点,即 for 循环很好,但这个带有 data.frame 列表的示例非常适合 lapply。
@arumbay 我还会检查ggplot2
包中的刻面以创建绘图组。
【参考方案1】:
为了进一步补充比斯特菲尔德的答案,您似乎想对每个数据帧执行一些复杂的操作。
apply 语句中可以有复杂的函数。那么您现在拥有的位置:
for (i in dflist)
# Do some complex things
这可以翻译成:
lapply(dflist, function(df)
# Do some complex operations on each data frame, df
# More steps
# Make sure the last thing is NULL. The last statement within the function will be
# returned to lapply, which will try to combine these as a list across all data frames.
# You don't actually care about this, you just want to run the function.
NULL
)
一个更具体的使用情节的例子:
# Assuming we have a data frame with our points on the x, and y axes,
lapply(dflist, function(df)
x2 <- df$x^2
log_y <- log(df$y)
plot(x,y)
NULL
)
您还可以编写带有多个参数的复杂函数:
lapply(dflist, function(df, arg1, arg2)
# Do something on each data.frame, df
# arg1 == 1, arg2 == 2 (see next line)
, 1, 2) # extra arguments are passed in here
希望对你有所帮助!
【讨论】:
谢谢你,这对我很有帮助,帮助我更好地理解了 apply 函数背后的原理!【参考方案2】:关于您的实际问题,您应该学习如何访问data.frame
s、matrix
s 或list
s 的单元格、行和列。从您的代码中,我猜您想访问data.frame i
的j
'th 列,所以它应该是:
mean( i[,j] )
# or
mean( i[[ j ]] )
$
运算符只能在您想访问 data.frame 中的特定变量时使用,例如i$var1
。此外,它的性能不如[, ]
或[[]]
访问。
然而,虽然没有错,但for
的使用会循环它不是很R'ish。您应该阅读有关矢量化函数和apply
系列的信息。所以你的代码可以很容易地重写为:
set.seed(42)
dflist <- vector( "list", 5 )
for( i in 1:5 )
dflist[[i]] <- data.frame( A = rnorm(100), B = rnorm(100), C = rnorm(100) )
varlist <- c("A", "B")
lapply( dflist, function(x) colMeans(x[varlist]) )
【讨论】:
谢谢 - 我担心我的 mean() 例子太简单了。我正在寻找一种方法来自动生成引用一组数据框的散点图(请参阅上面示例中的更改);我想这也可以使用 apply 函数?【参考方案3】:set.seed(42)
dflist <- list(data.frame(x=runif(10),y=rnorm(10)),
data.frame(x=rnorm(10),y=runif(10)))
par(mfrow=c(1,2))
for (i in dflist)
plot(y~x, data=i)
【讨论】:
【参考方案4】:以@Roland 为例,我想向您展示ggplot2
等价物。首先我们必须稍微改变一下数据集:
首先是原始数据:
> dflist
[[1]]
x y
1 0.9148060 -0.10612452
2 0.9370754 1.51152200
3 0.2861395 -0.09465904
4 0.8304476 2.01842371
5 0.6417455 -0.06271410
6 0.5190959 1.30486965
7 0.7365883 2.28664539
8 0.1346666 -1.38886070
9 0.6569923 -0.27878877
10 0.7050648 -0.13332134
[[2]]
x y
1 0.6359504 0.33342721
2 -0.2842529 0.34674825
3 -2.6564554 0.39848541
4 -2.4404669 0.78469278
5 1.3201133 0.03893649
6 -0.3066386 0.74879539
7 -1.7813084 0.67727683
8 -0.1719174 0.17126433
9 1.2146747 0.26108796
10 1.8951935 0.51441293
并将数据放入一个 data.frame 中,并带有一个 id 列
require(reshape2)
one_df = melt(dflist, id.vars = c("x","y"))
> one_df
x y L1
1 0.9148060 -0.10612452 1
2 0.9370754 1.51152200 1
3 0.2861395 -0.09465904 1
4 0.8304476 2.01842371 1
5 0.6417455 -0.06271410 1
6 0.5190959 1.30486965 1
7 0.7365883 2.28664539 1
8 0.1346666 -1.38886070 1
9 0.6569923 -0.27878877 1
10 0.7050648 -0.13332134 1
11 0.6359504 0.33342721 2
12 -0.2842529 0.34674825 2
13 -2.6564554 0.39848541 2
14 -2.4404669 0.78469278 2
15 1.3201133 0.03893649 2
16 -0.3066386 0.74879539 2
17 -1.7813084 0.67727683 2
18 -0.1719174 0.17126433 2
19 1.2146747 0.26108796 2
20 1.8951935 0.51441293 2
并制作情节:
require(ggplot2)
ggplot(one_df, aes(x = x, y = y)) + geom_point() + facet_wrap(~ L1)
【讨论】:
【参考方案5】:基于 Scott Ritchi 解决方案,这将是可重现的示例,同时隐藏来自 lapply 的反馈消息:
# split dataframe by condition on cars hp
f <- function() trunc(signif(mtcars$hp, 2) / 100)
dflist <- lapply(unique(f()), function(x) subset(mtcars, f() == x ))
这将mtcars
数据帧拆分为基于hp
变量分类的子集(0 表示低于 100 的马力,1 表示低于 100 的马力,2 表示 200 的马力,依此类推。)
然后,绘制它:
# use invisible to prevent the feedback message from lapply
invisible(
lapply(dflist, function(df)
x2 <- df$mpg^2
log_y <- log(df$hp)
plot(x2, log_y)
NULL
))
invisible()
将阻止lapply()
消息:
16
9
6
1
[[1]]
NULL
[[2]]
NULL
[[3]]
NULL
[[4]]
NULL
【讨论】:
以上是关于循环遍历数据框和变量名的主要内容,如果未能解决你的问题,请参考以下文章