【问题标题】:Update data.tables inside a list更新列表中的 data.tables
【发布时间】:2019-12-24 05:43:10
【问题描述】:

我想对 data.tables 列表应用一个函数来更新几列。问题是列表中的 data.tables 最终都具有相同的更改。这是一个可重现的示例:

library(data.table)
data("mtcars")
setDT(mtcars)


# Replicate dts in a list
dt_list <- rep(list(mtcars), 4)

# My Function
  update_dt <- function(i){ 
                            # new column
                            dt_list[[i]][, newcol := i]

                            # Updating column
                            dt_list[[i]][, mpg:= mpg + ((i-1)* 100)]
                            }

# Apply function
lapply(X= 1:length(dt_list), FUN= update_dt)

在这种情况下,我的 dt_list 中的所有 data.tables 最终都是相同的

【问题讨论】:

  • replicate(4, copy(mtcars))。当你把它变成一个 DT 时,它有一个单一的内存引用,并且它假定按引用语义,所以所有的变量都指向同一个内存位置。
  • 或先rep,然后再lapply(dt_list, setDT)
  • rbindlist(dt_list, idcol = "newcol")[, mpg := mpg + (newcol - 1)*100][]

标签: r list function data.table


【解决方案1】:

正如@r2evans 在 cmets 中提到的,通过复制 data.table,您只是在复制引用。相反,复制 data.frame 并将其设置为 data.table 作为函数的一部分。

library(data.table)
data("mtcars")



# Replicate dts in a list
dt_list <- rep(list(mtcars), 4)


# My Function
update_dt <- function(i){ 
  setDT(dt_list[[i]]) # Set as DT inside function
  # new column
  dt_list[[i]][, newcol := i]

  # Updating column
  dt_list[[i]][, mpg:= mpg + ((i-1)* 100)]
}

# Apply function
lapply(X= 1:length(dt_list), FUN= update_dt)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-13
    • 1970-01-01
    • 2012-08-28
    • 2015-09-07
    • 1970-01-01
    • 2016-03-24
    • 2022-01-09
    • 2019-11-24
    相关资源
    最近更新 更多