在 R 中导入数据集时跳过元数据
Skip metadata when Importing dataset in R
我的问题涉及在将数据导入 R 时如何跳过文件开头的元数据。我的数据是 .txt 格式,其中第一行
是描述数据的元数据,这些需要被过滤掉。
以下是制表符分隔格式的数据框的最小示例:
Type=GenePix Export
DateTime=2010/03/04 16:04:16
PixelSize=10
Wavelengths=635
ImageFiles=Not Saved
NormalizationMethod=None
NormalizationFactors=1
JpegImage=
StdDev=Type 1
FeatureType=Circular
Barcode=
BackgroundSubtraction=LocalFeature
ImageOrigin=150, 10
JpegOrigin=150, 2760
Creator=GenePix Pro 7.2.29.002
var1 var2 var3 var4 var5 var6 var7
1 1 1 molecule1 1F3 400 4020
1 2 1 molecule2 1B5 221 4020
1 3 1 molecule3 1H5 122 2110
1 4 1 molecule4 1D1 402 2110
1 5 1 molecule5 1F1 600 4020
如果我知道实际数据的起始行,我可以使用下面显示的基本命令:
mydata <- read.table("mydata.txt",header=T, skip=15)
哪个 return;
mydata
var1 var2 var3 var4 var5 var6 var7
1 1 1 1 molecule1 1F3 400 4020
2 1 2 1 molecule2 1B5 221 4020
3 1 3 1 molecule3 1H5 122 2110
4 1 4 1 molecule4 1D1 402 2110
5 1 5 1 molecule5 1F1 600 4020
问题是我需要编写一个脚本来读取各种数据集,其中实际数据开始的行号与一个不同
数据集到另一个。我可以想象使用 sqldf
包之类的东西,但我不太熟悉 sql.
如有任何帮助,我们将不胜感激。
假设如果所有文件都将 Creator
作为最后一个元数据行,
read.table(pipe("awk 'NR ==1, /Creator/ {next}{print}' mydata.txt"),
header=TRUE)
# var1 var2 var3 var4 var5 var6 var7
#1 1 1 1 molecule1 1F3 400 4020
#2 1 2 1 molecule2 1B5 221 4020
#3 1 3 1 molecule3 1H5 122 2110
#4 1 4 1 molecule4 1D1 402 2110
#5 1 5 1 molecule5 1F1 600 4020
如果知道列数,也可以
read.table(pipe("awk 'NF==7{print}' mydata.txt"), header=TRUE)
# var1 var2 var3 var4 var5 var6 var7
#1 1 1 1 molecule1 1F3 400 4020
#2 1 2 1 molecule2 1B5 221 4020
#3 1 3 1 molecule3 1H5 122 2110
#4 1 4 1 molecule4 1D1 402 2110
#5 1 5 1 molecule5 1F1 600 4020
更新
如果我们需要从 'var1' 的第一次出现开始读取到文件末尾,
read.table(pipe("awk '/var1/ { matched = 1}matched { print }' mydata.txt"),
header=TRUE)
# var1 var2 var3 var4 var5 var6 var7
#1 1 1 1 molecule1 1F3 400 4020
#2 1 2 1 molecule2 1B5 221 4020
#3 1 3 1 molecule3 1H5 122 2110
#4 1 4 1 molecule4 1D1 402 2110
#5 1 5 1 molecule5 1F1 600 4020
以上解决方案在 linux 系统上运行良好。在 Windows,它失败了(根据评论)。可以在两个系统上工作的选项是
lines <- readLines('mydata.txt')
read.table(text=lines[grep('var1', lines):length(lines)],header=TRUE)
# var1 var2 var3 var4 var5 var6 var7
#1 1 1 1 molecule1 1F3 400 4020
#2 1 2 1 molecule2 1B5 221 4020
#3 1 3 1 molecule3 1H5 122 2110
#4 1 4 1 molecule4 1D1 402 2110
#5 1 5 1 molecule5 1F1 600 4020
使用现有函数读取 DNA 微阵列数据如何?这些在 Bioconductor 项目开发的包中可用。
比如,大致是这样的
library(limma)
mydata<-read.maimages("mydata.txt", source="genepix")
有关更多示例,请参阅 limma manual。它可以轻松导入大多数 DNA 微阵列格式。
您可以使用 count.fields()
来确定 skip
参数。我把你的文件命名为"x.txt"
read.table("x.txt", skip = which.max(count.fields("x.txt") == 7) - 1,
header = TRUE)
# var1 var2 var3 var4 var5 var6 var7
# 1 1 1 1 molecule1 1F3 400 4020
# 2 1 2 1 molecule2 1B5 221 4020
# 3 1 3 1 molecule3 1H5 122 2110
# 4 1 4 1 molecule4 1D1 402 2110
# 5 1 5 1 molecule5 1F1 600 4020
所以这会在第一次出现七个字段时开始读取文件
基于实际数据(而不是元数据)中存在 表格 的解决方案。作为 "bonus",您可以选择显示(通过 cat
任何行都被视为元数据)。
主要阅读功能
read.genepix <- function(filename, disp.meta = FALSE) {
infile <- file(description = filename, open = "r" )
# create a meta indicator function
is.meta <- function(text) !grepl(pattern = "\t", x = text)
# Prepare to store meta text (if needed)
meta.text <- c()
meta <- TRUE
while(isTRUE(meta)) {
last.pos <- seek(infile, where = NA)
current.line <- readLines(infile, n = 1)
meta <- is.meta(current.line)
if(isTRUE(meta)) {
meta.text <- append(meta.text, current.line)
} else {
seek(infile, where = last.pos)
data.txt <- paste0(readLines(infile),collapse="\n")
close(infile)
break
}
}
if(isTRUE(disp.meta)) {
cat(paste(meta.text, collapse="\n"))
}
return(read.table(text=data.txt, header = TRUE, sep = "\t", quote=""))
}
用法/结果
my.data <- read.genepix("somefile.txt")
my.data
# var1 var2 var3 var4 var5 var6 var7
# 1 1 1 1 molecule1 1F3 400 4020
# 2 1 2 1 molecule2 1B5 221 4020
# 3 1 3 1 molecule3 1H5 122 2110
# 4 1 4 1 molecule4 1D1 402 2110
# 5 1 5 1 molecule5 1F1 600 4020
示例数据 在这个答案中使用(保存到磁盘为 "somefile.txt") - 但请注意,SO 用数据部分中的一系列空格替换制表符 - 所以在您的文本编辑器需要用表格替换这些空格才能使代码正常工作。
capture.output(cat("Type=GenePix Export
DateTime=2010/03/04 16:04:16
PixelSize=10
Wavelengths=635
ImageFiles=Not Saved
NormalizationMethod=None
NormalizationFactors=1
JpegImage=
StdDev=Type 1
FeatureType=Circular
Barcode=
BackgroundSubtraction=LocalFeature
ImageOrigin=150, 10
JpegOrigin=150, 2760
Creator=GenePix Pro 7.2.29.002
var1 var2 var3 var4 var5 var6 var7
1 1 1 molecule1 1F3 400 4020
1 2 1 molecule2 1B5 221 4020
1 3 1 molecule3 1H5 122 2110
1 4 1 molecule4 1D1 402 2110
1 5 1 molecule5 1F1 600 4020
"), file="somefile.txt")
您的问题的评论说明如下:
- 元数据部分不包含任何选项卡
- 数据部分以制表符分隔
因此,我猜测您的数据类似于本问题末尾的样本数据。
如果是这种情况,您可以使用 fread
的魔力来自动确定数据的起始位置。
这是一个演示:
cat(A, file = "mytest.txt", sep = "\n")
library(data.table)
fread("mytest.txt")
# var1 var2 var3 var4 var5 var6 var7
# 1: 1 1 1 molecule1 1F3 400 4020
# 2: 1 2 1 molecule2 1B5 221 4020
# 3: 1 3 1 molecule3 1H5 122 2110
# 4: 1 4 1 molecule4 1D1 402 2110
# 5: 1 5 1 molecule5 1F1 600 4020
示例数据:
A <- c("Type=GenePix Export", "DateTime=2010/03/04 16:04:16", "PixelSize=10",
"Wavelengths=635", "ImageFiles=Not Saved", "NormalizationMethod=None",
"NormalizationFactors=1", "JpegImage=", "StdDev=Type 1", "FeatureType=Circular",
"Barcode=", "BackgroundSubtraction=LocalFeature", "ImageOrigin=150, 10",
"JpegOrigin=150, 2760", "Creator=GenePix Pro 7.2.29.002",
"var1\tvar2\tvar3\tvar4\tvar5\tvar6\tvar7",
"1\t1\t1\tmolecule1\t1F3\t400\t4020", "1\t2\t1\tmolecule2\t1B5\t221\t4020",
"1\t3\t1\tmolecule3\t1H5\t122\t2110", "1\t4\t1\tmolecule4\t1D1\t402\t2110",
"1\t5\t1\tmolecule5\t1F1\t600\t4020")
A
# [1] "Type=GenePix Export"
# [2] "DateTime=2010/03/04 16:04:16"
# [3] "PixelSize=10"
# [4] "Wavelengths=635"
# [5] "ImageFiles=Not Saved"
# [6] "NormalizationMethod=None"
# [7] "NormalizationFactors=1"
# [8] "JpegImage="
# [9] "StdDev=Type 1"
# [10] "FeatureType=Circular"
# [11] "Barcode="
# [12] "BackgroundSubtraction=LocalFeature"
# [13] "ImageOrigin=150, 10"
# [14] "JpegOrigin=150, 2760"
# [15] "Creator=GenePix Pro 7.2.29.002"
# [16] "var1\tvar2\tvar3\tvar4\tvar5\tvar6\tvar7"
# [17] "1\t1\t1\tmolecule1\t1F3\t400\t4020"
# [18] "1\t2\t1\tmolecule2\t1B5\t221\t4020"
# [19] "1\t3\t1\tmolecule3\t1H5\t122\t2110"
# [20] "1\t4\t1\tmolecule4\t1D1\t402\t2110"
# [21] "1\t5\t1\tmolecule5\t1F1\t600\t4020"
我的问题涉及在将数据导入 R 时如何跳过文件开头的元数据。我的数据是 .txt 格式,其中第一行 是描述数据的元数据,这些需要被过滤掉。 以下是制表符分隔格式的数据框的最小示例:
Type=GenePix Export
DateTime=2010/03/04 16:04:16
PixelSize=10
Wavelengths=635
ImageFiles=Not Saved
NormalizationMethod=None
NormalizationFactors=1
JpegImage=
StdDev=Type 1
FeatureType=Circular
Barcode=
BackgroundSubtraction=LocalFeature
ImageOrigin=150, 10
JpegOrigin=150, 2760
Creator=GenePix Pro 7.2.29.002
var1 var2 var3 var4 var5 var6 var7
1 1 1 molecule1 1F3 400 4020
1 2 1 molecule2 1B5 221 4020
1 3 1 molecule3 1H5 122 2110
1 4 1 molecule4 1D1 402 2110
1 5 1 molecule5 1F1 600 4020
如果我知道实际数据的起始行,我可以使用下面显示的基本命令:
mydata <- read.table("mydata.txt",header=T, skip=15)
哪个 return;
mydata
var1 var2 var3 var4 var5 var6 var7
1 1 1 1 molecule1 1F3 400 4020
2 1 2 1 molecule2 1B5 221 4020
3 1 3 1 molecule3 1H5 122 2110
4 1 4 1 molecule4 1D1 402 2110
5 1 5 1 molecule5 1F1 600 4020
问题是我需要编写一个脚本来读取各种数据集,其中实际数据开始的行号与一个不同
数据集到另一个。我可以想象使用 sqldf
包之类的东西,但我不太熟悉 sql.
如有任何帮助,我们将不胜感激。
假设如果所有文件都将 Creator
作为最后一个元数据行,
read.table(pipe("awk 'NR ==1, /Creator/ {next}{print}' mydata.txt"),
header=TRUE)
# var1 var2 var3 var4 var5 var6 var7
#1 1 1 1 molecule1 1F3 400 4020
#2 1 2 1 molecule2 1B5 221 4020
#3 1 3 1 molecule3 1H5 122 2110
#4 1 4 1 molecule4 1D1 402 2110
#5 1 5 1 molecule5 1F1 600 4020
如果知道列数,也可以
read.table(pipe("awk 'NF==7{print}' mydata.txt"), header=TRUE)
# var1 var2 var3 var4 var5 var6 var7
#1 1 1 1 molecule1 1F3 400 4020
#2 1 2 1 molecule2 1B5 221 4020
#3 1 3 1 molecule3 1H5 122 2110
#4 1 4 1 molecule4 1D1 402 2110
#5 1 5 1 molecule5 1F1 600 4020
更新
如果我们需要从 'var1' 的第一次出现开始读取到文件末尾,
read.table(pipe("awk '/var1/ { matched = 1}matched { print }' mydata.txt"),
header=TRUE)
# var1 var2 var3 var4 var5 var6 var7
#1 1 1 1 molecule1 1F3 400 4020
#2 1 2 1 molecule2 1B5 221 4020
#3 1 3 1 molecule3 1H5 122 2110
#4 1 4 1 molecule4 1D1 402 2110
#5 1 5 1 molecule5 1F1 600 4020
以上解决方案在 linux 系统上运行良好。在 Windows,它失败了(根据评论)。可以在两个系统上工作的选项是
lines <- readLines('mydata.txt')
read.table(text=lines[grep('var1', lines):length(lines)],header=TRUE)
# var1 var2 var3 var4 var5 var6 var7
#1 1 1 1 molecule1 1F3 400 4020
#2 1 2 1 molecule2 1B5 221 4020
#3 1 3 1 molecule3 1H5 122 2110
#4 1 4 1 molecule4 1D1 402 2110
#5 1 5 1 molecule5 1F1 600 4020
使用现有函数读取 DNA 微阵列数据如何?这些在 Bioconductor 项目开发的包中可用。
比如,大致是这样的
library(limma)
mydata<-read.maimages("mydata.txt", source="genepix")
有关更多示例,请参阅 limma manual。它可以轻松导入大多数 DNA 微阵列格式。
您可以使用 count.fields()
来确定 skip
参数。我把你的文件命名为"x.txt"
read.table("x.txt", skip = which.max(count.fields("x.txt") == 7) - 1,
header = TRUE)
# var1 var2 var3 var4 var5 var6 var7
# 1 1 1 1 molecule1 1F3 400 4020
# 2 1 2 1 molecule2 1B5 221 4020
# 3 1 3 1 molecule3 1H5 122 2110
# 4 1 4 1 molecule4 1D1 402 2110
# 5 1 5 1 molecule5 1F1 600 4020
所以这会在第一次出现七个字段时开始读取文件
基于实际数据(而不是元数据)中存在 表格 的解决方案。作为 "bonus",您可以选择显示(通过 cat
任何行都被视为元数据)。
主要阅读功能
read.genepix <- function(filename, disp.meta = FALSE) {
infile <- file(description = filename, open = "r" )
# create a meta indicator function
is.meta <- function(text) !grepl(pattern = "\t", x = text)
# Prepare to store meta text (if needed)
meta.text <- c()
meta <- TRUE
while(isTRUE(meta)) {
last.pos <- seek(infile, where = NA)
current.line <- readLines(infile, n = 1)
meta <- is.meta(current.line)
if(isTRUE(meta)) {
meta.text <- append(meta.text, current.line)
} else {
seek(infile, where = last.pos)
data.txt <- paste0(readLines(infile),collapse="\n")
close(infile)
break
}
}
if(isTRUE(disp.meta)) {
cat(paste(meta.text, collapse="\n"))
}
return(read.table(text=data.txt, header = TRUE, sep = "\t", quote=""))
}
用法/结果
my.data <- read.genepix("somefile.txt")
my.data
# var1 var2 var3 var4 var5 var6 var7
# 1 1 1 1 molecule1 1F3 400 4020
# 2 1 2 1 molecule2 1B5 221 4020
# 3 1 3 1 molecule3 1H5 122 2110
# 4 1 4 1 molecule4 1D1 402 2110
# 5 1 5 1 molecule5 1F1 600 4020
示例数据 在这个答案中使用(保存到磁盘为 "somefile.txt") - 但请注意,SO 用数据部分中的一系列空格替换制表符 - 所以在您的文本编辑器需要用表格替换这些空格才能使代码正常工作。
capture.output(cat("Type=GenePix Export
DateTime=2010/03/04 16:04:16
PixelSize=10
Wavelengths=635
ImageFiles=Not Saved
NormalizationMethod=None
NormalizationFactors=1
JpegImage=
StdDev=Type 1
FeatureType=Circular
Barcode=
BackgroundSubtraction=LocalFeature
ImageOrigin=150, 10
JpegOrigin=150, 2760
Creator=GenePix Pro 7.2.29.002
var1 var2 var3 var4 var5 var6 var7
1 1 1 molecule1 1F3 400 4020
1 2 1 molecule2 1B5 221 4020
1 3 1 molecule3 1H5 122 2110
1 4 1 molecule4 1D1 402 2110
1 5 1 molecule5 1F1 600 4020
"), file="somefile.txt")
您的问题的评论说明如下:
- 元数据部分不包含任何选项卡
- 数据部分以制表符分隔
因此,我猜测您的数据类似于本问题末尾的样本数据。
如果是这种情况,您可以使用 fread
的魔力来自动确定数据的起始位置。
这是一个演示:
cat(A, file = "mytest.txt", sep = "\n")
library(data.table)
fread("mytest.txt")
# var1 var2 var3 var4 var5 var6 var7
# 1: 1 1 1 molecule1 1F3 400 4020
# 2: 1 2 1 molecule2 1B5 221 4020
# 3: 1 3 1 molecule3 1H5 122 2110
# 4: 1 4 1 molecule4 1D1 402 2110
# 5: 1 5 1 molecule5 1F1 600 4020
示例数据:
A <- c("Type=GenePix Export", "DateTime=2010/03/04 16:04:16", "PixelSize=10",
"Wavelengths=635", "ImageFiles=Not Saved", "NormalizationMethod=None",
"NormalizationFactors=1", "JpegImage=", "StdDev=Type 1", "FeatureType=Circular",
"Barcode=", "BackgroundSubtraction=LocalFeature", "ImageOrigin=150, 10",
"JpegOrigin=150, 2760", "Creator=GenePix Pro 7.2.29.002",
"var1\tvar2\tvar3\tvar4\tvar5\tvar6\tvar7",
"1\t1\t1\tmolecule1\t1F3\t400\t4020", "1\t2\t1\tmolecule2\t1B5\t221\t4020",
"1\t3\t1\tmolecule3\t1H5\t122\t2110", "1\t4\t1\tmolecule4\t1D1\t402\t2110",
"1\t5\t1\tmolecule5\t1F1\t600\t4020")
A
# [1] "Type=GenePix Export"
# [2] "DateTime=2010/03/04 16:04:16"
# [3] "PixelSize=10"
# [4] "Wavelengths=635"
# [5] "ImageFiles=Not Saved"
# [6] "NormalizationMethod=None"
# [7] "NormalizationFactors=1"
# [8] "JpegImage="
# [9] "StdDev=Type 1"
# [10] "FeatureType=Circular"
# [11] "Barcode="
# [12] "BackgroundSubtraction=LocalFeature"
# [13] "ImageOrigin=150, 10"
# [14] "JpegOrigin=150, 2760"
# [15] "Creator=GenePix Pro 7.2.29.002"
# [16] "var1\tvar2\tvar3\tvar4\tvar5\tvar6\tvar7"
# [17] "1\t1\t1\tmolecule1\t1F3\t400\t4020"
# [18] "1\t2\t1\tmolecule2\t1B5\t221\t4020"
# [19] "1\t3\t1\tmolecule3\t1H5\t122\t2110"
# [20] "1\t4\t1\tmolecule4\t1D1\t402\t2110"
# [21] "1\t5\t1\tmolecule5\t1F1\t600\t4020"