当标题有两个必要的标题行时,将文件读入R的最佳方法是什么?
这种情况一直发生在我身上,因为人们经常使用一行作为列名,然后在其下面包含另一行作为测量单位。我不想跳过任何东西。我希望名称和单位能够贯彻。
以下是typical file with two headers might look like:
的内容trt biomass yield
crop Mg/ha bu/ac
C2 17.76 205.92
C2 17.96 207.86
CC 17.72 197.22
CC 18.42 205.20
CCW 18.15 200.51
CCW 17.45 190.59
P 3.09 0.00
P 3.34 0.00
S2 5.13 49.68
S2 5.36 49.72
答案 0 :(得分:19)
我会做两个步骤,假设我们知道第一行包含标签,并且总是有两个标题。
header <- scan("file.txt", nlines = 1, what = character())
data <- read.table("file.txt", skip = 2, header = FALSE)
然后将字符向量header
添加为names
组件:
names(data) <- header
对于您的数据,这将是
header <- scan("data.txt", nlines = 1, what = character())
data <- read.table("data.txt", skip = 2, header = FALSE)
names(data) <- header
head(data)
> head(data)
trt biomass yield
1 C2 17.76 205.92
2 C2 17.96 207.86
3 CC 17.72 197.22
4 CC 18.42 205.20
5 CCW 18.15 200.51
6 CCW 17.45 190.59
如果你想要单位,按@ DWin的答案,那么在第2行再做一次scan()
header2 <- scan("data.txt", skip = 1, nlines = 1, what = character())
names(data) <- paste0(header, header2)
> head(data)
trtcrop biomassMg/ha yieldbu/ac
1 C2 17.76 205.92
2 C2 17.96 207.86
3 CC 17.72 197.22
4 CC 18.42 205.20
5 CCW 18.15 200.51
6 CCW 17.45 190.59
答案 1 :(得分:10)
使用readLines
和2作为限制,将其解析,paste0
将它们放在一起,然后使用read.table
和skip =2
以及header=FALSE
(默认情况下)通读)。通过分配列名完成该过程:
dat <- "trt biomass yield
crop Mg/ha bu/ac
C2 17.76 205.92
C2 17.96 207.86
CC 17.72 197.22
CC 18.42 205.20
CCW 18.15 200.51
CCW 17.45 190.59
P 3.09 0.00
P 3.34 0.00
S2 5.13 49.68
S2 5.36 49.72
"
您可能会使用文件参数,但使用读取函数的text
参数会使其更加自包含:
readLines(textConnection(dat),n=2)
#[1] "trt\tbiomass\tyield" "crop\tMg/ha\tbu/ac"
head2 <- read.table(text=readLines(textConnection(dat),n=2), sep="\t", stringsAsFactors=FALSE)
with(head2, paste0(head2[1,],head2[2,]) )
# [1] "trtcrop" "biomassMg/ha" "yieldbu/ac"
joinheadrs <- with(head2, paste0(head2[1,],head2[2,]) )
newdat <- read.table(text=dat, sep="\t",skip=2)
colnames(newdat)<- joinheadrs
#-------------------
> newdat
trtcrop biomassMg/ha yieldbu/ac
1 C2 17.76 205.92
2 C2 17.96 207.86
3 CC 17.72 197.22
4 CC 18.42 205.20
5 CCW 18.15 200.51
6 CCW 17.45 190.59
7 P 3.09 0.00
8 P 3.34 0.00
9 S2 5.13 49.68
10 S2 5.36 49.72
最好使用带有下划线的粘贴:
joinheadrs <- with(head2, paste(head2[1,],head2[2,] ,sep="_") )
joinheadrs
#[1] "trt_crop" "biomass_Mg/ha" "yield_bu/ac"
答案 2 :(得分:8)
与其他答案几乎相同的方法,只缩短为2个语句:
dat <- "trt biomass yield
crop Mg/ha bu/ac
C2 17.76 205.92
C2 17.96 207.86
CC 17.72 197.22
CC 18.42 205.20
CCW 18.15 200.51
CCW 17.45 190.59
P 3.09 0.00
P 3.34 0.00
S2 5.13 49.68
S2 5.36 49.72"
header <- sapply(read.table(text=dat, nrow=2), paste, collapse="_")
result <- read.table(text=dat, skip=2, col.names=header)
结果:
> head(result,2)
trt_crop biomass_Mg/ha yield_bu/ac
1 C2 17.76 205.92
2 C2 17.96 207.86
...
答案 3 :(得分:1)
略有不同的解释分步方法:
只读取文件的前两行作为数据(不带标题):
headers <- read.table("data.txt", nrows=2, header=FALSE)
使用两个(或更多)第一行创建标题名称,sappy
允许对列进行操作(在本例中为粘贴) - read more about sapply here:
headers_names <- sapply(headers,paste,collapse="_")
读取文件数据(跳过前两行):
data <- read.csv(file="data.txt", skip = 2, header=FALSE)
并将第二步的标题分配给数据:
names(data) <- headers_names
优势是您可以清楚地控制read.table的参数(例如逗号的sep
和stringAsFactors
- 用于标题和数据)
答案 4 :(得分:0)
这里是一项用于读取多行标题的功能,主要基于Gavin Simpson's excellent answer。
该函数默认使用逗号分隔值和两行标题,并以文件中的第一行作为标题返回data.frame
。
功能:
read.multi.line.header <- function(path, header.lines = 2, sep = ","){
header <- scan(path, nlines = 1, what = character(), sep = sep)
data <- read.table(path, skip = header.lines, header = FALSE, sep = sep)
base::names(data) <- header
return(data)
}
产生:
mydata <- read.multi.line.header(path = "data.txt")
> head(mydata)
trt biomass yield
1 C2 17.76 205.92
2 C2 17.96 207.86
3 CC 17.72 197.22
4 CC 18.42 205.20
5 CCW 18.15 200.51
6 CCW 17.45 190.59