【问题标题】:How to make "lists" or "vectors" of data frames如何制作数据框的“列表”或“向量”
【发布时间】:2014-11-22 10:59:55
【问题描述】:

关于我需要什么的小故事:我读过一个 CSV 文件,我想取出一些列并将它们作为自己的数据框存储到变量中,然后存储变量到列表中。但是,当我使用c() 执行此操作时,它只是将所有数据放在一个平面向量中。有没有办法获得数据框列表?

更长的故事:我读过一个 CSV 文件,假设它看起来像这样

,"Date","px high","px low","px last",,,,"Date","px high","px low","px last"
"eur curncy",03/Jan/2000,1.03,1.01,1.02,,,"gbp curncy",03/Jan/2000,1.64,1.61,1.64
,1/4/2000,1.03,1.02,1.03,,,,1/4/2000,1.64,1.63,1.64
,1/5/2000,1.04,1.03,1.03,,,,1/5/2000,1.65,1.64,"#N/A N/A"
,1/6/2000,1.04,1.03,1.03,,,,1/7/2000,1.65,1.64,1.65

当我存储读取的 CSV 文件并打印变量时,它看起来像

            Date        px.high    px.low    px.last    Date.1       px.high.1    px.low    px.last
eur curncy  03/Jan/2000 1.03       1.02      1.03       03/Jan/2000  1.64         1.63      1.64
            1/4/2000    1.03       1.02      1.03       1/4/2000     1.64         1.63      1.64
... etc.

为了避免混乱,我已经为这个示例删除了很多数据,但是这些数据还有更多的行和列。沿着它们在这些组中重复的列,每个组都有一个日期、px 高等。沿着这些行,您或多或少地与上面显示的最后几行相同。

我最终想深入每组数据,将其分割成月份,计算每一列中每个月的平均值,然后丢弃每日信息,然后为每组制作一个条形图。但是,我有以下问题需要解决:

  1. 第一行日期的格式与其他行不同。第一行之后的所有行都采用相同的格式。我可以自己通过读取数据来解决这个问题

cur <- read.csv('C:\\file.csv', stringsAsFactors=FALSE)

然后循环遍历列,在正确的位置分配

cur[1,col] <- as.character(as.date(cur[1,col], format='%d/%b/%Y'))

然后我可以通过循环遍历行和列来格式化其余的日期条目,然后基本上再次执行相同的操作。

  1. CSV 文件中的某些条目包含字符串“#N/A N/A”,我发现它会强制 R 将该列中的所有其他条目作为字符串读取,因此我无法再执行算术运算在物体上。我可以丢弃那些上面有这些的数据行,但即使这样做,列仍然是字符串。此外,如果我将这一行从其中一个组中丢弃,我会丢弃所有其余数据的整行,这是我不想这样做的。

算术问题很容易解决,当我做算术时,我只是将所有内容都转换为数字。它可能效率低下,但似乎效果很好。但是所有这些行都在同一个数据框中的问题,所以如果我丢弃一行,我也会丢弃该行上的所有其他数据——有时组的日期不匹配。因此,如果我为某个日期丢弃一行带有“#N/A N/A”的行,我会为其他组丢弃其他日期,这是我不想要的。因此,我能想到的最佳解决方案是将这些组拆分为它们自己的数据框,并在某种程度上分别对待它们。

  1. 某些数据的日期不匹配。我想基本上从这些数据组中的任何一组数据中丢弃任何日期,如果该日期没有被所有数据共享。但同样,我只想在所有组中的同一日期执行此操作——我不能只删除一行,因为该行可能再次对应于一组中的一个日期,但对应于另一组中的另一个日期。因此,似乎拆分组是要做的事情。

但如果有人认为有更好的方法,请告诉我。

【问题讨论】:

    标签: r csv dataframe


    【解决方案1】:

    要回答您关于列表的问题,是的,您可以将数据框存储在列表中:

    l <- list(dat1, dat2, dat3, etc.)
    

    如果您有奇数的 NA 值(999、-1、-11、#N/A 等),您可以使用 na.strings 捕获这些值并将您的列保留为数字:

    (dat <- read.csv(header = TRUE, na.strings = c('#N/A N/A'),
                    stringsAsFactors = FALSE,
                    text="Date,px high,px low,px last,
    03/Jan/2000,1.03,1.01,1.02,
    03/Jan/2000,1.64,1.61,1.64,
    1/4/2000,1.03,1.02,1.03,
    1/4/2000,1.64,1.63,1.64,
    1/5/2000,1.04,1.03,1.03,
    1/5/2000,1.65,1.64,#N/A N/A,
    1/6/2000,1.04,1.03,1.03,
    1/7/2000,1.65,1.64,1.65")[1:4])
    
    #          Date px.high px.low px.last
    # 1 03/Jan/2000    1.03   1.01    1.02
    # 2 03/Jan/2000    1.64   1.61    1.64
    # 3    1/4/2000    1.03   1.02    1.03
    # 4    1/4/2000    1.64   1.63    1.64
    # 5    1/5/2000    1.04   1.03    1.03
    # 6    1/5/2000    1.65   1.64      NA
    # 7    1/6/2000    1.04   1.03    1.03
    # 8    1/7/2000    1.65   1.64    1.65
    

    就像你说的,日期格式是混合的,所以我使用这个粗略的函数来检查使用哪种格式并告诉 R 使用正确的格式:

    f_dat <- function(x)
      as.Date(x, format = ifelse(is.na(as.numeric(gsub('/','',x))),
                                 '%d/%b/%Y', '%d/%m/%Y'))
    
    
    ## and format the dates:
    
    (dat <- within(dat, {
      Date <- f_dat(Date)
    }))
    
    #         Date px.high px.low px.last
    # 1 2000-01-03    1.03   1.01    1.02
    # 2 2000-01-03    1.64   1.61    1.64
    # 3 2000-04-01    1.03   1.02    1.03
    # 4 2000-04-01    1.64   1.63    1.64
    # 5 2000-05-01    1.04   1.03    1.03
    # 6 2000-05-01    1.65   1.64      NA
    # 7 2000-06-01    1.04   1.03    1.03
    # 8 2000-07-01    1.65   1.64    1.65
    

    编辑

    dat <- read.csv(header = TRUE, na.strings = c('#N/A N/A'),
                    stringsAsFactors = FALSE,
                    text=",Date,px high,px low,px last,,,,Date,px high,px low,px last
    eur curncy,03/Jan/2000,1.03,1.01,1.02,,,gbp curncy,03/Jan/2000,1.64,1.61,1.64
    ,1/4/2000,1.03,1.02,1.03,,,,1/4/2000,1.64,1.63,1.64
    ,1/5/2000,1.04,1.03,1.03,,,,1/5/2000,1.65,1.64,#N/A N/A
    ,1/6/2000,1.04,1.03,1.03,,,,1/7/2000,1.65,1.64,1.65")
    
    
    #            X        Date px.high px.low px.last X.1 X.2        X.3      Date.1 px.high.1 px.low.1 px.last.1
    # 1 eur curncy 03/Jan/2000    1.03   1.01    1.02  NA  NA gbp curncy 03/Jan/2000      1.64     1.61      1.64
    # 2               1/4/2000    1.03   1.02    1.03  NA  NA               1/4/2000      1.64     1.63      1.64
    # 3               1/5/2000    1.04   1.03    1.03  NA  NA               1/5/2000      1.65     1.64        NA
    # 4               1/6/2000    1.04   1.03    1.03  NA  NA               1/7/2000      1.65     1.64      1.65
    
    
    f_dat <- function(x)
      as.Date(x, format = ifelse(is.na(as.numeric(gsub('/','',x))),
                                 '%d/%b/%Y', '%d/%m/%Y'))
    
    (dat <- within(dat, {
      Date <- f_dat(Date)
      Date.1 <- f_dat(Date.1)
    }))
    
    #            X       Date px.high px.low px.last X.1 X.2        X.3     Date.1 px.high.1 px.low.1 px.last.1
    # 1 eur curncy 2000-01-03    1.03   1.01    1.02  NA  NA gbp curncy 2000-01-03      1.64     1.61      1.64
    # 2            2000-04-01    1.03   1.02    1.03  NA  NA            2000-04-01      1.64     1.63      1.64
    # 3            2000-05-01    1.04   1.03    1.03  NA  NA            2000-05-01      1.65     1.64        NA
    # 4            2000-06-01    1.04   1.03    1.03  NA  NA            2000-07-01      1.65     1.64      1.65
    

    【讨论】:

    • 为什么 CSV 代码无法使用?我大多只是从 CSV 文件中复制并剪切它。此外,您提供的数据并非应有的方式。当我打印你称为dat 的变量时,我应该得到一个不同的表。我将编辑原始帖子以显示它应该是怎样的。
    • 好吧,我并没有真正尝试过,但无论如何您都可以在您的数据上使用它。 @Addem 查看编辑
    • 因此,您的代码中有一些我以前从未见过的好东西肯定有助于解决格式问题,所以谢谢。但是,我仍然不确定如何解决我最大的问题,即删除数据的适当部分。例如,我希望能够删除第二组数据的第三行,因为它具有 NA 值。然后我想删除第一组值的相同日期。然后我还想删除第一组的第四个日期,因为它包含一个日期,2000-06-01,而另一个没有。
    • ...呃,没关系,完全忘记你告诉我如何将数据帧存储为列表。
    • 不能只删除第二组的第三行。您要么必须删除整行,要么将第二组第三行更改为 NA dat[3, 9:12] &lt;- NA 或任何适当的索引。然后您可以检查是否Date == Date.1,如果没有,则设置Date &lt;- NA
    猜你喜欢
    • 2021-01-20
    • 1970-01-01
    • 2013-07-04
    相关资源
    最近更新 更多