【问题标题】:How do I extract specific rows from a CSV and format the data in R?如何从 CSV 中提取特定行并在 R 中格式化数据?
【发布时间】:2019-06-12 08:48:17
【问题描述】:

我有一个包含数千行的 CSV 文件,如下所示:

1001;basket/files/legobrick.mp3
4096;basket/files/sunshade.avi
2038;data/lists/blockbuster.ogg
2038;data/random/noidea.dat

我想将其写入一个新的 CSV 文件,但只包含包含“.mp3”或“.avi”的行。输出文件应该只有一列,如下所示:

"basket/files/legobrick.mp3#1001",
"basket/files/sunshade.avi#4096",

所以第一列应该在第二列后加后缀,并用井号分隔,每一行都应该用引号括起来,并用逗号分隔,如上所示。

源 CSV 文件不包含带有列名的标题。这只是数据。

谁能告诉我如何在 R 中编写代码?

编辑(在标记答案之后):这个问题不是重复的,因为它涉及过滤行并且输出代码格式完全不同,需要不同的处理方法。标记的答案也完全不同,这确实支持了我的断言,即这不是重复的。

【问题讨论】:

  • 您可能需要阅读 greplgsub 的文档。
  • read.csv2()sprintf()
  • 不是重复的。在我的问题中,只应处理选定的行(取决于该行是否包含特定值),并且输出格式不同,需要不同的处理方法。

标签: r


【解决方案1】:

你可以通过以下方式做到这一点:

#Read the file with ; as separator
df <- read.csv2(text = text, header = FALSE, stringsAsFactors = FALSE)

#Filter the rows which end with "avi" or "mp3"
inds <- grepl("avi$|mp3$", df$V2)

#Create a new dataframe by pasting those rows with a separator
df1 <- data.frame(new_col = paste(df$V2[inds], df$V1[inds], sep = "#"))
df1

#                          new_col
#1 basket/files/legobrick.mp3#1001
#2  basket/files/sunshade.avi#4096

#Write the csv
write.csv(df1, "/path/of/file.csv", row.names = FALSE)

或者如果你想要它作为一个文本文件,你可以这样做

write.table(df1, "path/test.txt", row.names = FALSE, col.names = FALSE, eol = ",\n")

数据

text = "1001;basket/files/legobrick.mp3
4096;basket/files/sunshade.avi
2038;data/lists/blockbuster.ogg
2038;data/random/noidea.dat"

【讨论】:

  • 这看起来很棒,除了它是两列之外,它用引号将每一列括起来,并且不会在每一行后加逗号。如何使它看起来像这样:“basket/files/legobrick.mp3#1001”,(其中只有一列,每一行都被引用并以逗号为后缀)?
  • @Jstation 你想要它作为文本文件吗?使用write.table查看更新
  • @Jstation 如果您检查txt 文件,它在引号后有一个逗号后缀(")。
  • @Jstation 请使用write.table 写入文件,如答案所示。使用write.csv,您将无法看到“,”
  • 我很抱歉。我没有看到 write.table 修正。我按照您的指示将 write.csv 更改为 write.table,输出文件现在绝对完美。即使有成千上万的源文件行,处理速度也非常快。非常非常感谢,我非常感谢你,@Ronak Shah。
【解决方案2】:

看看下面的代码是否有帮助

library(tidyverse)
df %>% 
  filter(grepl("\\.mp3|\\.avi", file_path)) %>% 
  mutate(file_path = paste(file_path, ID, sep="#")) %>% 
  pull(file_path) %>% dput

【讨论】:

    【解决方案3】:

    data.table 答案:

    dt <- fread("file.csv")
    
    fwrite(dt[V2 %like% "mp3$|avi$", .(paste0(V2, "#", V1))], "output.csv", col.names = FALSE)
    

    【讨论】:

    • 这非常简洁,但会产生错误“is.list(x) is not TRUE”。我相信这是因为它试图将 CSV 文件作为数据表读取。如果我将 'data.table = FALSE' 添加到 'fread' 那么它可以读取 CSV 文件,但是 fwrite 无法访问这些列。源 CSV 完全如我的问题顶部所示。 Ronak Shah 的解决方案之所以有效,是因为它将源 CSV 作为文本读取,然后为输出数据创建一个新列。
    • 很抱歉没有成功。让我在几个小时内完成它,我不在电脑旁。
    • 查看修改后的代码。我添加了col.names = FALSE 参数以根据需要获取文件。
    • 哇@PavoDive 这太棒了,我喜欢它。它非常紧凑,过程就像闪电一样!说真的,干得好!
    • 这就是“f”在freadfwrite 中的含义:fast。这就是整体的 data.table 口头禅;)
    猜你喜欢
    • 2015-01-04
    • 1970-01-01
    • 2016-05-30
    • 2012-01-21
    • 2015-02-18
    • 1970-01-01
    • 2020-03-25
    • 1970-01-01
    • 2015-12-12
    相关资源
    最近更新 更多