在 R 循环中访问变量数据帧

Ale*_*lex 0 variables loops r dataframe

如果我在循环中使用数据框,如何使用可变数据框名称(以及可变列名称)来访问数据框内容?

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
    }
}
Run Code Online (Sandbox Code Playgroud)

ren*_*nsa 5

您可以使用get()基于名称字符串返回变量引用:

> x <- 1:10
> get("x")
[1]  1  2  3  4  5  6  7  8  9 10
Run Code Online (Sandbox Code Playgroud)

所以,是的,你可以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
    }
}
Run Code Online (Sandbox Code Playgroud)

不过,我真的认为这将是一种痛苦的方法。正如评论者所说,如果您可以将数据框放入一个列表中,然后对其进行迭代,它的性能可能会更好并且更具可读性。不幸的是,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
}
Run Code Online (Sandbox Code Playgroud)

希望有帮助!

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)
Run Code Online (Sandbox Code Playgroud)

这会带回一个已修改数据框的列表(尽管您可以使用map()map_dfr()和 的变体map_dfc()来分别自动地按行或按列绑定已处理的数据框列表。前者使用列名进行连接,而不是列位置,它还可以使用.id参数和输入列表的名称添加一个 ID 列。因此它带有一些不错的附加功能lapply()