在 R 循环中访问变量数据帧
Access variable dataframe in R loop
如果我在循环中处理数据框,我如何使用可变数据框名称(另外还有可变列名)来访问数据框内容?
dfnames <- c("df1","df2")
df1 <- df2 <- data.frame(X = sample(1:10),Y = sample(c("yes", "no"), 10, replace = TRUE))
for (i in seq_along(dfnames)){
curr.dfname <- dfnames[i]
#how can I do this:
curr.dfname$X <- 42:52
#...this
dfnames[i]$X <- 42:52
#or even this doubly variable call
for (j in 1_seq_along(colnames(curr.dfname)){
curr.dfname$[colnames(temp[j])] <- 42:52
}
}
您可以使用 get()
到 return 基于名称字符串的变量引用:
> x <- 1:10
> get("x")
[1] 1 2 3 4 5 6 7 8 9 10
所以,是的,您可以像这样遍历 dfnames
:
dfnames <- c("df1","df2")
df1 <- df2 <- data.frame(X = sample(1:10), Y = sample(c("yes", "no"), 10, replace = TRUE))
for (cur.dfname in dfnames)
{
cur.df <- get(cur.dfname)
# for a fixed column name
cur.df$X <- 42:52
# iterating through column names as well
for (j in colnames(cur.df))
{
cur.df[, j] <- 42:52
}
}
不过,我真的认为这将是一种痛苦的方法。正如评论者所说,如果您可以将数据框放入一个列表中,然后对其进行迭代,它可能会表现得更好并且更具可读性。不幸的是,据我所知,get()
没有矢量化,所以如果你只有一个数据框名称的字符串列表,你将不得不遍历它来获得一个数据框列表:
# build data frame list
df.list <- list()
for (i in 1:length(dfnames))
{
df.list[[i]] <- get(dfnames[i])
}
# iterate through data frames
for (cur.df in df.list)
{
cur.df$X <- 42:52
}
希望对您有所帮助!
2018年更新:我可能不会再做这样的事情了。相反,我将数据帧放在一个列表中,然后使用 purrr:map()
,或者基本等效项 lapply()
:
library(tidyverse)
stuff_to_do = function(mydata) {
mydata$somecol = 42:52
# … anything else I want to do to the current data frame
mydata # return it
}
df_list = list(df1, df2)
map(df_list, stuff_to_do)
这会返回修改后的数据框列表(尽管您可以使用 map()
、map_dfr()
和 map_dfc()
的变体来自动绑定已处理数据框的列表行- wise 或 column-wise 分别。前者使用列名来连接,而不是列位置,它还可以使用 .id
参数和输入列表的名称添加 ID 列。所以它带有一些不错的在 lapply()
!
上增加了功能
如果我在循环中处理数据框,我如何使用可变数据框名称(另外还有可变列名)来访问数据框内容?
dfnames <- c("df1","df2")
df1 <- df2 <- data.frame(X = sample(1:10),Y = sample(c("yes", "no"), 10, replace = TRUE))
for (i in seq_along(dfnames)){
curr.dfname <- dfnames[i]
#how can I do this:
curr.dfname$X <- 42:52
#...this
dfnames[i]$X <- 42:52
#or even this doubly variable call
for (j in 1_seq_along(colnames(curr.dfname)){
curr.dfname$[colnames(temp[j])] <- 42:52
}
}
您可以使用 get()
到 return 基于名称字符串的变量引用:
> x <- 1:10
> get("x")
[1] 1 2 3 4 5 6 7 8 9 10
所以,是的,您可以像这样遍历 dfnames
:
dfnames <- c("df1","df2")
df1 <- df2 <- data.frame(X = sample(1:10), Y = sample(c("yes", "no"), 10, replace = TRUE))
for (cur.dfname in dfnames)
{
cur.df <- get(cur.dfname)
# for a fixed column name
cur.df$X <- 42:52
# iterating through column names as well
for (j in colnames(cur.df))
{
cur.df[, j] <- 42:52
}
}
不过,我真的认为这将是一种痛苦的方法。正如评论者所说,如果您可以将数据框放入一个列表中,然后对其进行迭代,它可能会表现得更好并且更具可读性。不幸的是,据我所知,get()
没有矢量化,所以如果你只有一个数据框名称的字符串列表,你将不得不遍历它来获得一个数据框列表:
# build data frame list
df.list <- list()
for (i in 1:length(dfnames))
{
df.list[[i]] <- get(dfnames[i])
}
# iterate through data frames
for (cur.df in df.list)
{
cur.df$X <- 42:52
}
希望对您有所帮助!
2018年更新:我可能不会再做这样的事情了。相反,我将数据帧放在一个列表中,然后使用 purrr:map()
,或者基本等效项 lapply()
:
library(tidyverse)
stuff_to_do = function(mydata) {
mydata$somecol = 42:52
# … anything else I want to do to the current data frame
mydata # return it
}
df_list = list(df1, df2)
map(df_list, stuff_to_do)
这会返回修改后的数据框列表(尽管您可以使用 map()
、map_dfr()
和 map_dfc()
的变体来自动绑定已处理数据框的列表行- wise 或 column-wise 分别。前者使用列名来连接,而不是列位置,它还可以使用 .id
参数和输入列表的名称添加 ID 列。所以它带有一些不错的在 lapply()
!