【问题标题】:Deleting multiple columns in different data sets in R在R中删除不同数据集中的多列
【发布时间】:2012-09-19 16:37:21
【问题描述】:

我想知道是否有一种好方法可以删除 R 中几个不同数据集的多个列。我有一个看起来像这样的数据集:

RangeNumber    Time    Value    Quality    Approval
          1    2:00        1          1           1
          2    2:05        4          2           1

我想删除数据集中除时间和值列之外的所有内容。我通过将每一列设置为 NULL 来“删除”它们,例如:data1$RangeNumber <- NULL

我将拥有超过 16 个或更多具有相同列设置的数据集,并且数据集将按递增顺序编号,例如:data1、data2、data3 等。

我想知道循环遍历所有数据集列的 for 循环是否是完成此任务的最佳方法,或者——因为我已经读到 R 在 for 循环时很慢——如果有是一种更简单的方法。我还想知道是否需要将所有数据集合并到一个变量中,然后遍历以删除列。

如果for 循环是最好的方法,我将如何设置它?

【问题讨论】:

    标签: r for-loop


    【解决方案1】:

    您希望将这些数据帧收集到一个列表中,然后对它们运行提取函数。给“[”的第一个参数应该是 TRUE 以便获得所有行,第二个参数应该是列名(我组成了三个数据框,它们的行号和列名各不相同,但都有 'Time' 和 '值'列:

    > datlist <- list(dat1,dat2,dat3)
    > TimVal <- lapply(datlist, "[", TRUE, c("Time","Value") )
    > TimVal
    [[1]]
      Time Value
    1 2:00     1
    2 2:05     4
    
    [[2]]
      Time Value
    1 2:00     1
    2 2:05     4
    
    [[3]]
        Time Value
    1   2:00     1
    2   2:05     4
    2.1 2:05     4
    1.1 2:00     1
    

    如果目标是将它们全部放在同一个数据框中,则添加此内容:

    > do.call(rbind, TimVal)
        Time Value
    1   2:00     1
    2   2:05     4
    3   2:00     1
    4   2:05     4
    11  2:00     1
    21  2:05     4
    2.1 2:05     4
    1.1 2:00     1
    

    如果您对 R 非常陌生,您可能还没有发现最后的代码没有改变 TimVal;它只显示了将返回什么值,并且为了使效果持久,您需要分配一个名称。甚至可能是同一个名字:

    TimVal <- do.call(rbind, TimVal):
    

    【讨论】:

    • @qmoog,如果您预计必须对所有 16 个或更多数据集执行相同的计算,我也推荐这种方法。在这种情况下,拥有data.frames 中的list 会非常方便。
    • 这似乎是一个不错的方法。我现在就试试这个。
    • 这是一个很好的答案,因为它不仅允许我选择我需要的列,而且我可以在数据列表中运行另一个函数来将其他列设置为NULL。感谢@mrdwab 和@DWin
    • 我在遇到类似问题时遇到了这个解决方案,我想了解[lapply(datlist, "[", TRUE, c("Time","Value") )中的作用是什么?
    【解决方案2】:

    而不是删除,只需选择您想要的列,即

    data1 = data1[, c(2, 3)]
    

    关于您的其他数据集的问题仍然存在:data2 等。我怀疑由于您的数据框都是“相似的”,您可以将它们组合成一个带有额外标识符列的单个数据框,id ,它告诉你数据集的编号。如何组合数据集取决于数据的存储方式。但通常情况下,for 循环 read.csv 是可行的方法。

    【讨论】:

    • 由于我预计大多数数据帧都有约 50000 行数据,因此我试图通过删除我不需要的内容来了解​​内存使用情况。如果我决定合并它们,我喜欢 id 列的想法。
    【解决方案3】:

    我不确定我是否应该推荐这些,因为这些都是相当“破坏性”的方法......在尝试之前,请确保您有原始数据的备份;-)

    这种方法假定数据集已经在您的工作区中,而您只需要它们的新版本。

    这两者几乎相同。一种选择使用lapply(),另一种使用for

    • lapply

      lapply(ls(pattern = "data[0-9+]"),
             function(x) { assign(x, get(x)[2:3], envir = .GlobalEnv) })
      
    • for

      temp <- ls(pattern = "data[0-9+]")
      for (i in 1:length(temp)) {
        assign(temp[i], get(temp[i])[2:3])
      }
      

    基本上,ls(.etc.) 将在您的工作区中创建一个与您提供的命名模式相匹配的数据集向量。然后,编写一个小函数来选择要保留的列。

    一种“破坏性”较小的方法是创建新的data.frames,而不是覆盖原来的。像这样的东西应该可以解决问题:

    lapply(ls(pattern = "data[0-9+]"),
           function(x) { assign(paste(x, "T", sep="."), 
                                get(x)[2:3], envir = .GlobalEnv) })
    

    【讨论】:

    • 这是一个关于制作副本的公平点。我的数据来自只读源,因此无需担心删除无关的列。
    • @qmoog,好的。正如我在回答中提到的那样,我从您提出问题的方式假设数据集已经在您的工作区中,因此建议采用这种方法。
    • 不用担心。我应该在我原来的问题中提到这一点。
    猜你喜欢
    • 1970-01-01
    • 2020-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多