【问题标题】:How do I create a copy of a data frame in R如何在 R 中创建数据框的副本
【发布时间】:2016-01-24 23:57:35
【问题描述】:

我想复制从 *.csv 文件中读取的数据框的全部内容。如果我这样做copyOfFirstFrame <- firstFrame,我不相信这是重复的。那么我需要做什么呢?

firstFrame <- read_csv("fileName.csv")
copyOfFirstFrame <- ?????

如果我执行以下操作,内存地址保持不变。

copyOfFirstFrame <- firstFrame
tracemem(firstFrame) == tracemem(copyOfFirstFrame)
[1] TRUE

复制必须产生两个唯一的内存地址。详情请查看In R, how can I check if two variable names reference the same underlying object?

【问题讨论】:

  • 如果我这样做并比较内存地址,它们仍然是内存中的同一个对象。我已更新问题详情

标签: r dataframe


【解决方案1】:

令 DATA 为预先存在的数据框对象。 我正在创建一个新对象 COPY,它是 DATA 的精确副本,但它占用不同的内存位置,因此不指向原始数据帧。

我像这样使用函数 data.frame():

> COPY<-data.frame(DATA)

我使用tracemem()检查内存地址是否相同:

> tracemem(COPY)==tracemem(DATA)
> [1] FALSE

我觉得够蹩脚的。

【讨论】:

  • This answer 表明set方法仍然可以同时编辑两个data.frames。
【解决方案2】:

将 cbind 与一个 data.frame 一起使用将确保您拥有一份副本:

> df <- cbind(NA, NA)
> df2 <- cbind(df)
> df2
     [,1] [,2]
[1,]   NA   NA
> df2[,1] <- 1
> df
     [,1] [,2]
[1,]   NA   NA
> df2
     [,1] [,2]
[1,]    1   NA
> 

【讨论】:

  • This answer 表明set方法仍然可以同时编辑两个data.frames。
【解决方案3】:

我们也可以使用data.table::copy()

df.1 <- data.frame(1)

library(data.table)
df.2 <- copy(df.1)

> tracemem(df.1) == tracemem(df.2)
[1] FALSE

【讨论】:

    【解决方案4】:

    无论是 cbind() 还是 data.frame,添加了变量或更改了变量名称,都不会将原始数据框与 data.table 的 set() 函数所做的修改隔离到数据框的副本。

    > library(data.table)
    > # changing name of variable in copy doesn't work, emp modified
    > (emp <- data.frame(type=c('a','b','c'),amt=as.numeric(c(1,2,3))))
      type amt
    1    a   1
    2    b   2
    3    c   3
    > (dd <- cbind(emp,dv=''))
      type amt dv
    1    a   1   
    2    b   2   
    3    c   3   
    > names(dd)[names(dd)=='type'] <- 'tp'
    > i <- which(dd$tp=='a'); set(dd,i,'tp','alpha')
    > i <- which(dd$tp=='b'); set(dd,i,'tp','beta')
    > i <- which(dd$tp=='c'); set(dd,i,'tp','chi')
    > dd
         tp amt dv
    1 alpha   1   
    2  beta   2   
    3   chi   3   
    > emp
       type amt
    1 alpha   1
    2  beta   2
    3   chi   3
    > dd$dv <- factor(dd$dv)
    > table(dd$dv)
    > table(emp$type)
    
        a     b     c alpha  beta   chi 
        0     0     0     1     1     1 
    > tracemem(dd)==tracemem(emp)
    [1] FALSE
    > 
    > # same w/ data.frame doesn't work, emp still modified
    > (emp <- data.frame(type=c('a','b','c'),amt=as.numeric(c(1,2,3))))
      type amt
    1    a   1
    2    b   2
    3    c   3
    > (dd <- data.frame(emp,dv=1))
      type amt dv
    1    a   1  1
    2    b   2  1
    3    c   3  1
    > names(dd)[names(dd)=='type'] <- 'tp'
    > i <- which(dd$tp=='a'); set(dd,i,'tp','alpha')
    > i <- which(dd$tp=='b'); set(dd,i,'tp','beta')
    > i <- which(dd$tp=='c'); set(dd,i,'tp','chi')
    > dd$tp <- factor(dd$tp)
    > table(dd$tp)
    
    alpha  beta   chi 
        1     1     1 
    > table(emp$type)
    
        a     b     c alpha  beta   chi 
        0     0     0     1     1     1 
    > tracemem(dd)==tracemem(emp)
    [1] FALSE
    > 
    > # only modifying new variable insulates emp
    > (emp <- data.frame(type=c('a','b','c'),amt=as.numeric(c(1,2,3))))
      type amt
    1    a   1
    2    b   2
    3    c   3
    > (dd <- cbind(emp,dv=''))
      type amt dv
    1    a   1   
    2    b   2   
    3    c   3   
    > names(dd)[names(dd)=='type'] <- 'tp'
    > i <- which(dd$tp=='a'); set(dd,i,'dv','alpha')
    > i <- which(dd$tp=='b'); set(dd,i,'dv','beta')
    > i <- which(dd$tp=='c'); set(dd,i,'dv','chi')
    > dd
      tp amt    dv
    1  a   1 alpha
    2  b   2  beta
    3  c   3   chi
    > emp
      type amt
    1    a   1
    2    b   2
    3    c   3
    > table(emp$type)
    
    a b c 
    1 1 1 
    > tracemem(dd)==tracemem(emp)
    [1] FALSE
    > 
    

    【讨论】:

    • 但是使用library(data.table) 的副本确实可以避免这些:在dd &lt;- copy(emp) 之后,编辑到dd 不要更改emp
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-24
    • 2014-08-19
    • 2010-10-26
    • 1970-01-01
    • 2021-12-24
    • 2019-05-12
    • 2018-06-23
    相关资源
    最近更新 更多