【问题标题】:Removing attributes of columns in data.frames on multilevel lists in R在 R 中的多级列表上删除 data.frames 中列的属性
【发布时间】:2015-05-06 13:19:15
【问题描述】:

如何动态删除 R 中嵌套列表中 data.frames 的以下列的属性?

List of 1
 $ 0021400001:List of 19
   $ GameSummary      :'data.frame':    1 obs. of  13 variables:
    $ GAME_DATE_EST                   : Factor w/ 1 level "2014-11-09T00:00:00": 1
      - attr(*, "names")= chr "1"
    $ GAME_SEQUENCE                   : Factor w/ 1 level "2": 1
      - attr(*, "names")= chr "2"
    $ GAME_ID                         : Factor w/ 1 level "0021400091": 1
      - attr(*, "names")= chr "3"
    $ GAME_STATUS_ID                  : Factor w/ 1 level "3": 1
      - attr(*, "names")= chr "4" 
   $ SeasonSeries     :'data.frame':    1 obs. of  7 variables:
     $ GAME_ID         : Factor w/ 1 level "0021400001": 1
      - attr(*, "names")= chr "1"
     $ HOME_TEAM_ID    : Factor w/ 1 level "1610612740": 1
      - attr(*, "names")= chr "2"
     $ VISITOR_TEAM_ID : Factor w/ 1 level "1610612753": 1
      - attr(*, "names")= chr "3"

【问题讨论】:

  • 这个结构是从哪里来的?来源是JSON?用什么包? names 属性以某种方式保留给值名称
  • 制作了我自己的脚本,以使来自 nba.com 的 json 文件具有可读性和结构化。
  • 你能dput 至少提供这个对象的一个​​小样本吗?
  • 我发现摆脱大量变量的大量属性的最简单方法是将我的 data.frame 转换为 matrix

标签: r list


【解决方案1】:

在此线程上回答可能为时已晚,但我想分享。

两种解决方案: 1. merTools包中的stripAttributes函数。

  1. 从数据框 MyData 中的变量 VAR 中删除属性 ATT:

    attr(MyData$VAR, "ATT") <- NULL
    

如果要删除所有变量的几个属性:

For (var in colnames(MyData)) {
     attr(MyData[,deparse(as.name(var))], "ATT_1") <- NULL
     attr(MyData[,deparse(as.name(var))], "ATT_2") <- NULL
}

我希望这会有所帮助, 问候

【讨论】:

    【解决方案2】:

    您可以编写一个对列表中的一个条目起作用的函数,例如

    one_entry <- function(x) {
        for (i in length(x)) attr(x[[i]], "names") <- NULL
        return(x)
    }
    

    然后运行lapply:

    lapply(my_list, FUN=one_entry)
    

    mylist 是问题中的数据结构。

    【讨论】:

      【解决方案3】:

      这是一个 hack,但在我的情况下有效。

      lapply(my_list, FUN=function(x){data.frame(as.matrix(x),stringsAsFactors = F)})
      

      【讨论】:

        【解决方案4】:

        对 Parisa 的代码稍作修改对我有用:

        for (var in colnames(MyData)) {
          attr(MyData[[deparse(as.name(var))]], "ATT_1") <- NULL
          attr(MyData[[deparse(as.name(var))]], "ATT_2") <- NULL
        }
        

        【讨论】:

          【解决方案5】:

          在已经说过的所有内容的基础上,下面的代码将为数据df 中的所有变量保留一些属性并删除其他属性。只需替换要保留在向量to_keep 中的属性即可。在这种情况下,我假设我想保留属性“label”和“at1”——当然,假设它们存在。

          to_keep <- c("label", "at1")
          
          to_keep_regx <- paste(to_keep, collapse = "|")
            
          nn  <- names(df)
          for (x in seq_along(nn)) {
            
            ats       <- attributes(df[[x]])
            atsn      <- names(ats)
            to_remove <- atsn[!grepl(to_keep_regx, atsn)]
            
            for (i in seq_along(to_remove)) {
              attr(df[[x]], to_remove[i]) <- NULL
            }
          
          }
          
          

          最好的,

          【讨论】:

            【解决方案6】:

            在这种情况下,当您想删除 names 时,您可以使用 unname 仅与 lapply 结合使用:

            dat[] <- lapply(dat, unname)
            

            [] 用于确保结果仍然是data.frame。您可以使用c 删除几乎所有其他属性:

            dat[] <- lapply(dat, c)
            

            例如,考虑:

            # setup data.frame to use
            dat <- list(X1 = setNames(factor(1:3), letters[1:3]), 
                        X2 = setNames(factor(4:6), LETTERS[1:3]))
            attr(dat$X1, "xyz") <- "abc"
            attr(dat$X2, "abc") <- "xyz"
            dat <- as.data.frame(dat)
            
            # remove attributes that are not names
            dat[] <- lapply(dat, c) # use [] to preserve data.frame
            str(dat) # no attributes. No names either but those are never added in R 3.6.3
            
            # try with list instead
            dat <- list(X1 = setNames(factor(1:3), letters[1:3]), 
                        X2 = setNames(factor(4:6), LETTERS[1:3]))
            attr(dat$X1, "xyz") <- "abc"
            attr(dat$X2, "abc") <- "xyz"
            
            # remove names
            dat <- lapply(dat, unname) # no need for []
            str(dat) # still has other attributes but not names
            

            详情

            来自help("c")

            ...除名称之外的所有属性都被删除。

            例外适用于因子和整数。请参阅手册页。

            【讨论】:

              【解决方案7】:

              Karsten W. 的回答对我有用,因为我必须删除 2 个以上的属性。稍微修改为

              my_list <- lapply(my_list, FUN=one_entry)
              

              【讨论】:

                【解决方案8】:

                使用utilities包中的rm.attr函数

                您可以使用utilities package 中的rm.attr 函数从对象中删除属性。该函数删除输入对象的所有非保护属性;它允许您指定不想删除的受保护属性。对于嵌套列表的输入对象,该函数还允许您指定列表中您希望对其应用删除的级别数。

                由于您在问题中没有给出可重现的数据示例,因此我将向您展示一个改编自该函数文档的示例。首先我们生成一个带有属性的嵌套列表对象,并展示它的结构。

                #Create an object with attributes
                a <- structure(list(structure(1, x=2, names=3),
                               list(0, structure(3, x=4, names=5))),
                               x=3, names = 4)
                
                #Show the structure of the object
                str(a)
                List of 2
                 $ 4 : Named num 1
                  ..- attr(*, "x")= num 2
                  ..- attr(*, "names")= chr "3"
                 $ NA:List of 2
                  ..$ : num 0
                  ..$ : Named num 3
                  .. ..- attr(*, "x")= num 4
                  .. ..- attr(*, "names")= chr "5"
                 - attr(*, "x")= num 3
                

                现在我们可以查看删除了指定级别属性的同一个对象。 (请注意,默认情况下,names 属性是受保护的属性,但您可以根据需要更改此属性。)

                #Show the structure with one level of attributes removed
                str(rm.attr(a, list.levels = 1))
                List of 2
                 $ 4 : Named num 1
                  ..- attr(*, "names")= chr "3"
                 $ NA:List of 2
                  ..$ : num 0
                  ..$ : Named num 3
                  .. ..- attr(*, "x")= num 4
                  .. ..- attr(*, "names")= chr "5"
                
                #Show the structure with two levels of attributes removed
                str(rm.attr(a, list.levels = 2))
                List of 2
                 $ 4 : Named num 1
                  ..- attr(*, "names")= chr "3"
                 $ NA:List of 2
                  ..$ : num 0
                  ..$ : Named num 3
                  .. ..- attr(*, "names")= chr "5"
                

                【讨论】:

                  猜你喜欢
                  • 2017-05-08
                  • 2020-02-04
                  • 1970-01-01
                  • 1970-01-01
                  • 2019-09-29
                  • 2016-06-18
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多