Считывание отформатированных данных в R

#r

Вопрос:

Я пытаюсь использовать stdin для чтения данных в R. Я хочу прочитать данные в следующем формате:

 5       #rows matrix A
7       #cols matrix A
0 1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31 32 33 34
3       #rows matrix B
4       #cols matrix B
0 1 2 3
4 5 6 7
8 9 10 11
100     #param1
-7      #param2
9       #param3
 

Пример того, как я хотел бы прочитать данные, лучше всего иллюстрируется следующим кодом на языке си:

 #include <stdio.h>
#include <stdlib.h>

int* readMatrix(int rows, int cols) {
    int* matrix = (int*) malloc(rows*cols*sizeof(int));
    for (int i = 0; i < rows*cols;   i) {
        scanf("%d", amp;matrix[i]);
    }
    return matrix;
}

int main() {
    int a_rows, a_cols; 
    int b_rows, b_cols;
    int *a, *b;
    int param1, param2, param3;

    scanf("%d %d", amp;a_rows, amp;a_cols);
    a = readMatrix(a_rows, a_cols);

    scanf("%d %d", amp;b_rows, amp;b_cols);
    b = readMatrix(b_rows, b_cols);

    scanf("%d %d %d", amp;param1, amp;param2, amp;param3);

    return 0;
}
 

Мой «эквивалентный» R-код выглядит примерно так:

 a_rows <- scan(file="stdin", what=integer(0), n=1);
a_cols <- scan(file="stdin", what=integer(0), n=1);
A <- matrix(scan(file="stdin", n = a_rows*a_cols), a_rows, a_cols, byrow = TRUE)

b_rows <- scan(file="stdin", what=integer(0), n=1);
b_cols <- scan(file="stdin", what=integer(0), n=1);
B <- matrix(scan(file="stdin", n = b_rows*b_cols), b_rows, b_cols, byrow = TRUE)

param1 <- scan(file="stdin", what=integer(0), n=1);
param2 <- scan(file="stdin", what=integer(0), n=1);
param3 <- scan(file="stdin", what=integer(0), n=1);
 

Конечно, это не работает, и я получаю следующий вывод при запуске сценария R:

 Read 1 item
Read 0 items
Read 0 items
Error in matrix(scan(file = "stdin", n = a_rows * a_cols), a_rows, a_cols,  :
  invalid 'ncol' value (too large or NA)
Execution halted
 

На самом деле, если я попытаюсь прочитать только первые два значения:

 a_rows <- scan(file="stdin", what=integer(0), n=1);
a_cols <- scan(file="stdin", what=integer(0), n=1);
 

Я получаю следующее сообщение:

 Read 1 item
Read 0 items
 

У кого-нибудь есть хорошее решение этой проблемы? Я пытался найти больше информации о scan функции, но не могу найти ничего о том, почему я получаю такое поведение.

ПРАВКА 1 Я использую R версии 3.1.0

 R version 3.1.0 (2014-04-10) -- "Spring Dance"
Copyright (C) 2014 The R Foundation for Statistical Computing
Platform: x86_64-unknown-linux-gnu (64-bit)
 

ПРАВКА 2
Я нашел решение, код R выглядит следующим образом:

 sin <- file("stdin");
open(sin);

a_rows <- scan(sin, what=integer(0), n=1);
a_cols <- scan(sin, what=integer(0), n=1);
A <- matrix(scan(sin, n = a_rows*a_cols), a_rows, a_cols, byrow = TRUE)

b_rows <- scan(sin, what=integer(0), n=1);
b_cols <- scan(sin, what=integer(0), n=1);
B <- matrix(scan(sin, n = b_rows*b_cols), b_rows, b_cols, byrow = TRUE)

param1 <- scan(sin, what=integer(0), n=1);
param2 <- scan(sin, what=integer(0), n=1);
param3 <- scan(sin, what=integer(0), n=1);
 

Почему я должен открывать stdin , я не знаю.

Ответ №1:

Я внес три незначительных изменения в ваш код, и затем он работает:

  1. Используйте nlines=... вместо n=...
  2. Используйте file=stdin() вместо file="stdin"
  3. Используйте what=integer() вместо what=integer(0)

Примечание: У меня есть подозрение, что nlines=... здесь важно только это. Другие изменения, возможно, не нужны.

Попробуй это:

 a_rows <- scan(file=stdin(), what=integer(), nlines=1);
a_cols <- scan(file=stdin(), what=integer(), nlines=1);
A <- matrix(scan(file=stdin(), nlines = a_rows), a_rows, a_cols, byrow = TRUE)
print(A)
 

Затем я отправлю файл:

 > source('~/.active-rstudio-document')
1: 2
Read 1 item
1: 3
Read 1 item
1: 1
2: 2
Read 2 items
> source('~/.active-rstudio-document')
1: 2
Read 1 item
1: 3
Read 1 item
1: 1 2 3
4: 4 5 6
Read 6 items
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
 

Комментарии:

1. Привет, я пытался использовать ваш код для чтения матрицы, но получил следующую ошибку: Error in scan(file, what, nmax, sep, dec, quote, skip, nlines, na.strings, : scan() expected 'an integer', got 'a_cols' . Если я изменюсь file=stdin() на file="stdin" , я получу ту же ошибку, что и в моем исходном сообщении. Стоит упомянуть, что я бегу: R version 3.1.0 (2014-04-10) -- "Spring Dance" Copyright (C) 2014 The R Foundation for Statistical Computing Platform: x86_64-unknown-linux-gnu (64-bit)