【问题标题】:String separated by \n to dataframe由 \n 分隔的字符串到数据框
【发布时间】:2018-09-29 16:39:30
【问题描述】:

我有以下字符串:

  "Title\nToday 1,239 €\nYesterday 1,2 €\n17/04/2018 1,2 €\n14/04/2018 1,2 €\n13/04/2018 1,2 €\n12/04/2018 1,2 €\n11/04/2018 1,2 €\n09/04/2018 1,2 €\n08/04/2018 1,2 €\n07/04/2018 1,2 €"

但我不知道是否可以从中获取数据框。我想用我的字符串获取一个包含两列(日期和价格)的数据框,如下所示(实际上不需要Title 名称):

Date       Price
Today      1,239 €
Yesteday   1,2 €
17/04/2018 1,2 €
14/04/2018 1,2 €
13/04/2018 1,2 €
12/04/2018 1,2 €
11/04/2018 1,2 €
09/04/2018 1,2 €
08/04/2018 1,2 €
07/04/2018 1,2 €

这与我使用cat 函数可以得到的几乎相同。但我想我可以将它转换为数据框。 有什么想法吗?

【问题讨论】:

    标签: r string dataframe cat


    【解决方案1】:

    这里有read.table的解决方案:

    > read.table(text=str, sep=' ', skip=1, col.names=c('Date', 'Price', 'Currency'))
             Date Price Currency
    1       Today 1,239        €
    2   Yesterday   1,2        €
    3  17/04/2018   1,2        €
    4  14/04/2018   1,2        €
    5  13/04/2018   1,2        €
    6  12/04/2018   1,2        €
    7  11/04/2018   1,2        €
    8  09/04/2018   1,2        €
    9  08/04/2018   1,2        €
    10 07/04/2018   1,2        €
    

    str 是您的数据。请注意参数skip 正在删除“标题”。

    【讨论】:

    • 如果你想把两列(价格和货币)放在一起,你可以用data.frame(Date=df$Date, Price=paste(df$Price, df$Currency))df作为上述命令的数据框
    • 简单而优雅——我喜欢它+1(我自己运行它,而不是“€”我得到“”——知道为什么吗?)
    • 一些编码问题...您正在运行哪个操作系统?
    【解决方案2】:

    我建议做这样的事情来将你的字符串s 转换为data.frame。这个想法是将日期、值和单位分开,以便更轻松地处理数据,因为您将单位和数字条目分开。

    df <- do.call(rbind.data.frame, strsplit(
        unlist(strsplit(sub("Title\n", "", s), "\n")),
        " "))
    colnames(df) <- c("Date", "Value", "Unit");
    df$Value <- as.numeric(as.character(sub(",", ".", df$Value)));
    #         Date Value Unit
    #1       Today 1.239    €
    #2   Yesterday 1.200    €
    #3  17/04/2018 1.200    €
    #4  14/04/2018 1.200    €
    #5  13/04/2018 1.200    €
    #6  12/04/2018 1.200    €
    #7  11/04/2018 1.200    €
    #8  09/04/2018 1.200    €
    #9  08/04/2018 1.200    €
    #10 07/04/2018 1.200    €
    

    解释:我们首先在"\n" 上拆分s,然后在空格上分离出DateValueUnit。由于您的值包含逗号小数分隔符“,”,因此我们将“,”替换为“。”并转换为numeric


    您可以通过以下方式避免sub("Title\n", "", s)(感谢@PoGibas),使其更加紧凑:

    df <- do.call(rbind.data.frame, strsplit(unlist(strsplit(s, "\n"))[-1], " "))
    colnames(df) <- c("Date", "Value", "Unit");
    df$Value <- as.numeric(as.character(sub(",", ".", df$Value)));
    

    输出同上。


    样本数据

    s <-   "Title\nToday 1,239 €\nYesterday 1,2 €\n17/04/2018 1,2 €\n14/04/2018 1,2 €\n13/04/2018 1,2 €\n12/04/2018 1,2 €\n11/04/2018 1,2 €\n09/04/2018 1,2 €\n08/04/2018 1,2 €\n07/04/2018 1,2 €"
    

    【讨论】:

    • 您可以在第一个strsplit 输出上使用[-1] 而不是sub
    • 谢谢@PoGibas;我进行了编辑以包含您的建议。
    【解决方案3】:

    这是strsplitdplyr::separate 的解决方案。

    prices <- "Title\nToday 1,239 €\nYesterday 1,2 €\n17/04/2018 1,2 €\n14/04/2018 1,2 €\n13/04/2018 1,2 €\n12/04/2018 1,2 €\n11/04/2018 1,2 €\n09/04/2018 1,2 €\n08/04/2018 1,2 €\n07/04/2018 1,2 €"
    
    prices <- data.frame(x = strsplit(prices, "\n", "", fixed = TRUE)[[1]])
    prices <- prices %>% separate(x, " ", into = c("Date", "Prices"), extra = "merge") 
    prices <- prices[-1,]
    prices
    #          Date  Prices
    # 2       Today 1,239 €
    # 3   Yesterday   1,2 €
    # 4  17/04/2018   1,2 €
    # 5  14/04/2018   1,2 €
    # 6  13/04/2018   1,2 €
    # 7  12/04/2018   1,2 €
    # 8  11/04/2018   1,2 €
    # 9  09/04/2018   1,2 €
    # 10 08/04/2018   1,2 €
    # 11 07/04/2018   1,2 €
    

    【讨论】:

      【解决方案4】:

      我已经实现了几次strsplit,然后我构建了一个matrix,它被转换为一个数据框(通过取矩阵的第 1 列和第 2 列来删除 € 符号):

      # Making a short object containing your string
      x <- "Title\nToday 1,239 €\nYesterday 1,2 €\n17/04/2018 1,2 €\n14/04/2018 1,2 €\n13/04/2018 1,2 €\n12/04/2018 1,2 €\n11/04/2018 1,2 €\n09/04/2018 1,2 €\n08/04/2018 1,2 €\n07/04/2018 1,2 €"
      
      # Two string splits (first splitting by "\n" and then by " "), and discarding the "title" (by taking [[1]][2:11])
      x <- unlist(strsplit(strsplit(x, split = "\n")[[1]][2:11], split = " "))
      
      # Putting it in a data frame (dropping the € symbol)
      df1 <- data.frame(matrix(x, ncol = 3, byrow = T)[,1:2])
      

      结果:

      > df1
                 X1    X2
      1       Today 1,239
      2   Yesterday   1,2
      3  17/04/2018   1,2
      4  14/04/2018   1,2
      5  13/04/2018   1,2
      6  12/04/2018   1,2
      7  11/04/2018   1,2
      8  09/04/2018   1,2
      9  08/04/2018   1,2
      10 07/04/2018   1,2
      

      我还想将“,”添加到“。”并将值作为数字

      x <- unlist(strsplit(strsplit(x, split = "\n")[[1]][2:11], split = " "))
      x <- gsub(",", ".", x)
      df1 <- data.frame(matrix(x, ncol = 3, byrow = T)[,1:2])
      df1[,2] <- as.numeric(levels(df1[,2]))[df1[,2]]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-14
        • 1970-01-01
        • 1970-01-01
        • 2022-12-19
        相关资源
        最近更新 更多