【问题标题】:Dataframes in a list; adding a new variable with name of dataframe列表中的数据框;添加具有数据框名称的新变量
【发布时间】:2011-10-27 18:38:31
【问题描述】:

我有一个数据框列表,我最终想要合并这些数据框,同时保留其原始数据框名称或列表索引的记录。这将允许我在所有行中对等进行子集化。为此,我想为每个数据帧添加一个新变量“id”,其中包含它所属的数据帧的名称/索引。

编辑:“在我的真实代码中,数据帧变量是通过使用以下代码读取多个文件创建的,因此我没有实际名称,只有 'files.to.read' 列表中的那些我不确定是否它们将与数据框顺序对齐:

mylist <- llply(files.to.read, read.csv)

在几篇文章中强调了一些方法: Working-with-dataframes-in-a-list-drop-variables-add-new-onesUsing-lapply-with-changing-arguments

我试过两种类似的方法,第一种使用索引列表:

df1 <- data.frame(x=c(1:5),y=c(11:15))
df2 <- data.frame(x=c(1:5),y=c(11:15))
mylist <- list(df1,df2)

# Adds a new coloumn 'id' with a value of 5 to every row in every dataframe.
# I WANT to change the value based on the list index.
mylist1 <- lapply(mylist, 
    function(x){
        x$id <- 5
        return (x)
    }
)
#Example of what I WANT, instead of '5'.
#> mylist1
#[[1]]
  #x  y id
#1 1 11  1
#2 2 12  1
#3 3 13  1
#4 4 14  1
#5 5 15  1
#
#[[2]]
  #x  y id
#1 1 11  2
#2 2 12  2
#3 3 13  2
#4 4 14  2
#5 5 15  2

第二次尝试传递列表的names()。

# I WANT it to add a new coloumn 'id' with the name of the respective dataframe
# to every row in every dataframe.
mylist2 <- lapply(names(mylist), 
    function(x){
        portfolio.results[[x]]$id <- "dataframe name here"
        return (portfolio.results[[x]])
    }
)
#Example of what I WANT, instead of 'dataframe name here'.
# mylist2
#[[1]]
  #x  y id
#1 1 11  df1
#2 2 12  df1
#3 3 13  df1
#4 4 14  df1
#5 5 15  df1
#
#[[2]]
  #x  y id
#1 1 11  df2
#2 2 12  df2
#3 3 13  df2
#4 4 14  df2
#5 5 15  df2

但是 names() 函数不适用于数据帧列表;它返回 NULL。 我可以在第一个示例中使用 seq_along(mylist) 吗?

处理整个“与源 ID 合并”的任何想法或更好的方法

编辑 - 在下面添加了解决方案:我已经使用 Hadleys 的建议和 Tommy 的轻推实现了一个解决方案,看起来像这样。

files.to.read <- list.files(datafolder, pattern="\\_D.csv$", full.names=FALSE)
mylist <- llply(files.to.read, read.csv)
all <- do.call("rbind", mylist)
all$id <- rep(files.to.read, sapply(mylist, nrow))

我使用 files.to.read 向量作为每个数据帧的 id

我也从使用 merge_recurse() 改变了,因为它由于某种原因非常慢。

 all <- merge_recurse(mylist)

谢谢大家。

【问题讨论】:

    标签: list r dataframe names lapply


    【解决方案1】:

    个人觉得折叠后加名字比较容易:

    df1 <- data.frame(x=c(1:5),y=c(11:15))
    df2 <- data.frame(x=c(1:5),y=c(11:15))
    mylist <- list(df1 = df1, df2 = df2)
    
    all <- do.call("rbind", mylist)
    all$id <- rep(names(mylist), sapply(mylist, nrow))
    

    【讨论】:

    • 谢谢 我不确定折叠是否会保留订单。我正在折叠列表以使用 qplot() 并通过 $id 指定子集。但是,崩溃的速度非常慢,所以我对其他选择持开放态度。
    • 哇,我在实际代码中使用 rbind() 而不是 merge_recurse(),总时间从 ~10 分钟减少到 10 秒。
    【解决方案2】:

    您的第一次尝试非常接近。通过使用索引而不是值,它将起作用。您的第二次尝试失败了,因为您没有命名列表中的元素。

    以下两种解决方案都使用lapply 可以将额外参数(mylist)传递给函数的事实。

    df1 <- data.frame(x=c(1:5),y=c(11:15))
    df2 <- data.frame(x=c(1:5),y=c(11:15))
    mylist <- list(df1=df1,df2=df2) # Name each data.frame!
    # names(mylist) <- c("df1", "df2") # Alternative way of naming...
    
    # Use indices - and pass in mylist
    mylist1 <- lapply(seq_along(mylist), 
            function(i, x){
                x[[i]]$id <- i
                return (x[[i]])
            }, mylist
    )
    
    # Now the names work - but I pass in mylist instead of using portfolio.results.
    mylist2 <- lapply(names(mylist), 
        function(n, x){
            x[[n]]$id <- n
            return (x[[n]])
        }, mylist
    )
    

    【讨论】:

    • 感谢您回答这两个问题。我编辑了我的问题,声明我没有名字,但我确实有。将 files.to.read 转换为列表允许我为每个列表元素分配相应的名称,前提是它们正确对齐......我没有看到树木的树林!
    【解决方案3】:

    names() 可以工作它有名字,但你没有给它任何名字。这是一个未命名的列表。您将需要使用数字索引:

    > for(i in 1:length(mylist) ){ mylist[[i]] <- cbind(mylist[[i]], id=rep(i, nrow(mylist[[i]]) ) ) }
    > mylist
    [[1]]
      x  y id
    1 1 11  1
    2 2 12  1
    3 3 13  1
    4 4 14  1
    5 5 15  1
    
    [[2]]
      x  y id
    1 1 11  2
    2 2 12  2
    3 3 13  2
    4 4 14  2
    5 5 15  2
    

    【讨论】:

    • 谢谢。在汤米、哈德利和你自己之间,我创建了一个合适的解决方案。我最终想要在这个过程中进一步识别这些名字。
    【解决方案4】:

    dlply 函数形式的 plyr 包可能是一个答案:

    library('plyr')
    df1 <- data.frame(x=c(1:5),y=c(11:15))
    df2 <- data.frame(x=c(1:5),y=c(11:15))
    mylist <- list(df1 = df1, df2 = df2)
    
    all <- ldply(mylist)
    

    【讨论】:

      猜你喜欢
      • 2017-09-13
      • 2020-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-14
      • 2019-10-31
      相关资源
      最近更新 更多