Я прилагаю вам решение на основе data.table
:
library(data.table)
my.df <- data.frame(a = rnorm(10,5), b= rnorm(10,5), c=rnorm(10,5), d=rnorm(10,5), e=rnorm(10,5))
my.df <- as.data.table(my.df)
my.df[my.df[,(sum(a<=.SD)<=2) | (sum(b<=.SD)<=2), by=seq_len(nrow(my.df))]$V1]
Вы можете узнать, сколько байтов на самом деле вернуло StreamReader
(в отличие от чтения из потока) несколькими способами, ни один из которых не слишком прост I ' я боюсь.
textReader.CurrentEncoding.GetByteCount (totalLengthOfAllTextRead)
, а затем ищите эту позицию в потоке. StreamReader
, который соответствует текущей позиции байта во внутреннем буфере (отличается от того, что с потоком - обычно позади, но, конечно, не более чем равен). Судя по .NET Reflector, эта переменная, кажется, называется bytePos
.
, но вместо этого реализуйте пользовательскую функцию ReadLine, построенную поверх потока Stream
или BinaryReader
даже ( BinaryReader
гарантированно никогда не читать дальше, чем вы просите). Эта пользовательская функция должна считывать из потока char в char, так что вам действительно придется использовать низкоуровневый объект Decoder
(если только кодировка не ASCII / ANSI, в этом случае все немного проще из-за к однобайтовому кодированию). Вариант 1 будет наименее эффективным, как я себе представляю (так как вы эффективно перекодируете текст, который вы только что декодировали), а вариант 3 труднее всего реализовать, хотя, пожалуй, самый элегантный , Я бы, вероятно, рекомендовал не использовать некрасивый взлом отражения (вариант 2), хотя это выглядит заманчиво, будучи самым прямым решением и занимая всего пару строк. (Если честно, класс StreamReader действительно должен предоставлять эту переменную через открытое свойство, но, увы, нет.) В конце концов, решать вам, но метод 1 или 3 должен выполняйте работу достаточно хорошо ...
Надеюсь, это поможет.
Таким образом, данные представляют собой utf8 (кодировка по умолчанию для StreamReader). Это многобайтовая кодировка, поэтому IndexOf будет нежелательным. Вы можете:
Encoding.UTF8.GetByteCount(string)
на ваших данных, добавив 1 или 2 байта для конца отсутствующей строки.
Если вам нужно подсчитать байты, я бы пошел с BinaryReader. Вы можете взять результаты и привести их в соответствие с необходимостью, но я считаю, что его представление о его текущем положении более надежно (поскольку оно читает в двоичном виде, оно неуязвимо для проблем с набором символов).
Итак, ваша последняя строка содержит «ДАННЫЕ» + неизвестное количество байтов данных. Вы можете извлечь позицию, используя IndexOf () с вашей последней прочитанной строкой. Затем перенастройте поток. Положение.
Но я не уверен, стоит ли вообще использовать ReadLine () в этом случае. Возможно, было бы лучше читать побайтово, пока вы не достигнете отметки «DATA».
Разрывы строк легко идентифицируются без необходимости предварительного декодирования потока (за исключением некоторых кодировок, редко используемых для текстовых файлов, таких как EBCDIC, UTF-16, UTF-32), поэтому можно просто прочитать каждую строку как байты, а затем декодировать всю строку:
using (FileStream stream = File.OpenRead(path)) {
List<byte> buffer = new List<byte>();
bool hasCr = false;
bool done = false;
while (!done) {
int b = stream.ReadByte();
if (b == -1) throw new IOException("End of file reached in header.");
if (b == 13) {
hasCr = true;
} else if (b == 10 && hasCr) {
string line = Encoding.UTF8.GetString(buffer.ToArray(), 0, buffer.Count);
if (line == "DATA") {
done = true;
} else {
HandleHeaderLine(line);
}
buffer.Clear();
hasCr = false;
} else {
if (hasCr) buffer.Add(13);
hasCr = false;
buffer.Add((byte)b);
}
}
_dataOffset = stream.Position;
}
Вместо того, чтобы закрывать поток и открывать его снова,