在R中读取两行标题

Naz*_*zer 23 file-io r

当标题有两个必要的标题行时,将文件读入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)

然后将角色向量添加headernames组件:

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 =2header=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)


the*_*ail 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)
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)