当标题有两个必要的标题行时,将文件读入R的最佳方法是什么?
这种情况一直发生在我身上,因为人们经常使用一行作为列名,然后在其下面包含另一行作为测量单位.我不想跳过任何东西.我想要名字和单位进行.
以下是具有两个标头的典型文件可能如下所示:
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
Run Code Online (Sandbox Code Playgroud)
Rei*_*son 20
我会做两个步骤,假设我们知道第一行包含标签,并且总是有两个标题.
header <- scan("file.txt", nlines = 1, what = character())
data <- read.table("file.txt", skip = 2, header = FALSE)
Run Code Online (Sandbox Code Playgroud)
然后将角色向量添加header为names组件:
names(data) <- header
Run Code Online (Sandbox Code Playgroud)
对于您的数据,这将是
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
Run Code Online (Sandbox Code Playgroud)
如果你想要单位,按@ DWin的答案,那么scan()在第2行做一秒
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
Run Code Online (Sandbox Code Playgroud)
42-*_*42- 10
使用readLines2作为限制,解析它们,paste0它们一起,然后使用read.tablewith 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
"
Run Code Online (Sandbox Code Playgroud)
您可能会使用文件参数,但使用textread函数的参数会使其更加自包含:
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
Run Code Online (Sandbox Code Playgroud)
可能更好地使用带有下划线的粘贴:
joinheadrs <- with(head2, paste(head2[1,],head2[2,] ,sep="_") )
joinheadrs
#[1] "trt_crop" "biomass_Mg/ha" "yield_bu/ac"
Run Code Online (Sandbox Code Playgroud)
几乎与其他答案相同的方法,只缩短为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)
Run Code Online (Sandbox Code Playgroud)
结果:
> head(result,2)
trt_crop biomass_Mg/ha yield_bu/ac
1 C2 17.76 205.92
2 C2 17.96 207.86
...
Run Code Online (Sandbox Code Playgroud)