【问题标题】:iterate over a set of dataframes in R遍历 R 中的一组数据帧
【发布时间】:2020-04-26 09:42:32
【问题描述】:

假设我有一组数据框:df1, df2, d3, df4。我想对这些数据帧中的每一个应用某种行为。我不想重复复制代码,而是想通过某种 for 循环来做到这一点。例如,假设我想获取 df 并重新分配它,以便第一列是行名。我这样做的正常方式是:

df1_b <- df1[,-1]
rownames(df1_b) <- df1[,1]

我将如何对我拥有的所有四个数据框执行此操作。我想我需要以某种方式将数据帧组合成一个 set,然后执行类似

的操作
for (i in set) {
  i+"_b" <- i[,-1]
  rownames(i_b) <- i[,1]
}

我尝试使用 cbind 来做到这一点:

df_set <- c(df1, df2, df3, df4)
for (i in df_set) {
  i+"_b" <- i[,-1]
  rownames(i_b) <- i[,1]
}

但这当然不起作用(我很确定 R 不会像这样进行字符串连接)。

任何帮助将不胜感激!

【问题讨论】:

  • 你是对的,R 没有那样连接,但你可以使用paste(i, "b", sep = "_")。但是您最好制作一个数据框列表并使用lapply 或purrr::map 之类的东西对其进行迭代。已经有很多这样的帖子了

标签: r dataframe for-loop


【解决方案1】:

我们可以使用mget将多个对象的值放入list,然后通过list和lapply循环在list中进行处理

lst1 <- lapply(mget(paste0("df", 1:4)), function(x) {
               row.names(x) <- x[,1]
                x[,-1]
    })

如果我们想改变原来的对象(不推荐)

list2env(lst1, .GlobalEnv)

或者另一个选项是tidyverse

library(purrr)
library(tibble)
library(dplyr)
mget(ls(pattern = "^df\\d+$")) %>%
     map(~ .x %>%
               column_to_rownames(names(.)[1])) 

【讨论】:

  • 谢谢。我真的很喜欢 tidyverse 解决方案。有了它,您是否必须在 R 中使用 map 与 for 循环?我想这并不重要。
  • @BOBjwjwj3j3j for 循环也有效。我不喜欢创建多个对象,所以想把它保存在list
  • 太棒了。最后一个问题:在这种情况下,columns_to_rownames 解决方案返回“在.data 中找不到列1。”。我认为这是因为第一列的第一个单元格是一个字符串(并且每个 df 之间的不同)。有没有办法在索引 [,1] 处指定事物?
  • @BOBjwjwj3j3j 抱歉,应该是column_to_rownames(names(.)[1])
【解决方案2】:

您可以通过这种方式应用函数,例如:

# getting some dummy data
df1 <- mtcars
df2 <- mtcars
df3 <- mtcars
df4 <- mtcars

lst <- list(df1, df2, df3, df4)

# example of applying the function row.names to the data
Map(row.names, lst)

【讨论】:

    猜你喜欢
    • 2021-06-25
    • 2021-11-22
    • 2017-12-14
    • 2020-06-11
    • 2021-03-14
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多