Чтение двухстрочных заголовков в R - программирование
Подтвердить что ты не робот

Чтение двухстрочных заголовков в 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
4b9b3361

Ответ 1

Я бы сделал два шага, полагая, что мы знаем, что первая строка содержит метки, и всегда есть два заголовка.

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, затем сделали вторую 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

Ответ 2

Используйте 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

Возможно, лучше использовать пасту с подчеркиванием-sep:

joinheadrs <- with(head2, paste(head2[1,],head2[2,] ,sep="_")  )
joinheadrs
#[1] "trt_crop"      "biomass_Mg/ha" "yield_bu/ac"  

Ответ 3

Практически такой же метод для других ответов, только сокращение до 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
...

Ответ 4

Несколько отличающийся подход шаг за шагом:

  • Прочитайте только первые две строки файлов как данные (без заголовков):

    headers <- read.table("data.txt", nrows=2, header=FALSE)
    
  • Создайте имена заголовков с двумя (или более) первыми строками, sappy позволяет делать операции над столбцами (в этом случае вставлять) - подробнее о sapply здесь:

    headers_names <- sapply(headers,paste,collapse="_")
    
  • Прочитайте данные файлов (пропустив первые 2 строки):

    data <- read.csv(file="data.txt", skip = 2, header=FALSE)
    
  • И присвойте заголовкам второго шага данные:

    names(data) <- headers_names
    

Преимущество заключается в том, что у вас будет четкое управление параметрами read.table(например, sep для запятых и stringAsFactors - для заголовков и данных)

Ответ 5

Вот функция для чтения в заголовках по нескольким строкам, в значительной степени основанная на превосходном ответе Гевина Симпсона.

Функция по умолчанию использует значения, разделенные запятыми, и две строки заголовка и возвращает 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