【问题标题】:Add column containing data frame name to a list of data frames [duplicate]将包含数据框名称的列添加到数据框列表中[重复]
【发布时间】:2014-12-02 20:41:28
【问题描述】:

如果我有一个数据框列表

my_list = list(data, data2, data3)

我想为每个填充了该数据框名称的列添加一列

column1    column2    new_column    
12         27         data
27         987        data
378        1234       data

,我该怎么办?我希望集合中的所有 DF 都保留其原始名称,但也让它填充一列。

我试过了:

my_list = lapply(my_list, function(DF){
     DF$new_column <- DF

     DF
})

但它不会遍历函数内的列表。

我错过了什么?谢谢

【问题讨论】:

  • DF 不是名称,而是data.frame。查看stackoverflow.com/questions/10520772/… 并将函数内的DF 替换为deparse(substitute(DF))。有帮助吗?
  • 如果您使用list(data, data2, data3) 创建列表,则有关数据帧名称的信息将丢失。
  • @SvenHohenstein 这很有道理——所以它不会像每个元素的内容一样将它们存储为“列表元素 1”、列表元素 2 等?

标签: r


【解决方案1】:

您的列表未命名。您可以在创建时手动命名它

my_list = list(data = data, data2 = data2, data3 = data3)

如果您有很多数据集,也可以使用mget & ls 组合

my_list <- mget(ls(pattern = "^data$|^data\\d+$"))

之后,只需使用Map

my_list <- Map(cbind, my_list, new_clumn = names(my_list))
my_list
# $data
#   column1 column2 new_clumn
# 1      12      27      data
# 2      27     987      data
# 3     378    1234      data
# 
# $data2
#   column1 column2 new_clumn
# 1      12      27     data2
# 2      27     987     data2
# 3     378    1234     data2
# 
# $data3
#   column1 column2 new_clumn
# 1      12      27     data3
# 2      27     987     data3
# 3     378    1234     data3

#If you want to put the data sets back to the global environment you can use `list2env`
#list2env(my_list, .GlobalEnv) 
#Please Note that it is usually not the preffered practice to move data frames to the global environment and back. It is preferred to store all you data sets in list from the very beginning and manipulating them within the list using functions such as `Map`, `lapply`, etc.

【讨论】:

  • 主要区别在于给定初始示例中的列表不包含名称。否则添加这些名称将是微不足道的。
  • 这就像列表中的魅力一样。不过,它并没有解压列表来更改环境中的原始数据帧。我猜我只需要弄清楚如何从列表中删除数据框并使用另一个函数将它们放回全局环境中?
  • 太完美了。谢谢!
【解决方案2】:

我改变了,现在看看这是不是你想要的:

names<-names(my_list)
count <- 0
lapply(my_list, function(DF){
    count <<- count+1
    DF[,length(DF)+1] <- names[count]
    names(DF)[length(DF)] <- "new_clumn"
    DF
})

【讨论】:

  • 这不起作用...在上面的代码中,您在实际创建第三列之前为第三列分配了一个名称。
  • 嗯我明白你的意思了,现在我看到你的回答我明白他想要什么了
  • 这个问题很清楚,甚至还有一个例子;)
  • 是的,你说得对,我完全误解了他的话
【解决方案3】:
> x <- data.frame(1:2, 2:1)
> my_list <- list(a = x, b = x)
> my_list
$a
  X1.2 X2.1
1    1    2
2    2    1

$b
  X1.2 X2.1
1    1    2
2    2    1

> your_new_list <- lapply(names(my_list),
+                           function(current_name)
+                               transform(my_list[[current_name]],
+                                         new_column = current_name))
> your_new_list
[[1]]
  X1.2 X2.1 new_column
1    1    2          a
2    2    1          a

[[2]]
  X1.2 X2.1 new_column
1    1    2          b
2    2    1          b

【讨论】:

  • 而且,如果你不熟悉变换,你可以这样做:lapply(names(my_list), function(current_name) { my_list[[current_name]]$new_column = current_name; my_list })
  • 这会返回一个 0 的列表?
  • 哦!对,错字!将最后一个 my_list 替换为 my_list[[current_name]]...对不起! (或者只使用transform 版本:-)
  • 我替换(并使用了 OP 解决方案,并且都返回空列表
  • 我认为原始解决方案(使用transform)不会返回一个空列表...我已更新解决方案的帖子以包含完整的输入/输出以进行演示。干杯!
猜你喜欢
  • 2019-10-31
  • 1970-01-01
  • 2015-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-02
  • 2018-08-20
相关资源
最近更新 更多