ヘッダーにヘッダーに2つの必要な行がある場合、ファイルをRに読み込む最良の方法は何ですか?
多くの場合、列名に1行を使用し、その下に別の行を測定単位に含めるため、これは常に私に起こります。何もスキップしたくない。名前とユニットを引き継いでほしい。
これが 2つのヘッダーを持つ典型的なファイルは次のようになるかもしれません です:
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
最初の行にラベルが含まれ、ヘッダーが常に2つあることを前提として、2つのステップを実行します。
_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行目で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
_
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
"
おそらくファイル引数を使用しますが、read-functionsに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
下線-sepでペーストを使う方が良いかもしれません:
joinheadrs <- with(head2, paste(head2[1,],head2[2,] ,sep="_") )
joinheadrs
#[1] "trt_crop" "biomass_Mg/ha" "yield_bu/ac"
他の回答とほぼ同じ方法で、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
...
少し異なる説明ステップバイステップアプローチ:
ファイルの最初の2行のみをデータ(ヘッダーなし)として読み取ります。
headers <- read.table("data.txt", nrows=2, header=FALSE)
最初の2行(またはそれ以上)でヘッダー名を作成します。sappy
を使用すると、列を操作できます(この場合は貼り付けます)- sapplyの詳細はこちら :
headers_names <- sapply(headers,paste,collapse="_")
ファイルのデータを読み取ります(最初の2行をスキップします)。
data <- read.csv(file="data.txt", skip = 2, header=FALSE)
そして、ステップ2のヘッダーをデータに割り当てます。
names(data) <- headers_names
利点は、read.tableのパラメーター(コンマの場合はsep
、ヘッダーとヘッダーの両方の場合はstringAsFactors
など)を明確に制御できることです。データ)
これは、主に Gavin Simpsonの優れた答え に基づいて、複数行にわたってヘッダーを読み取る関数です。
関数はデフォルトでカンマ区切りの値と2行のヘッダーになり、ファイルの最初の行をヘッダーとして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