Это легко с dplyr
, если вы хотите изменить значения для столбцов V1
и V2
на основе значений в V3
. Мы можем указать столбцы, для которых мы хотим изменить значения, в mutate_at
, а в аргументе funs
указать условие, для которого вы хотите изменить значения.
library(dplyr)
data %>% mutate_at(vars(V1:V2), funs(replace(., V3 == 1 & . == 0, NA)))
# id V1 V2 V3
#1 A 1 NA 1
#2 B 0 0 0
#3 C NA NA 1
Файл на 2 ГБ является довольно большим, и необходимо знать обо всех возможных областях, которые могут действовать как узкие места:
Я запустил бы путем выполнения некоторых измерений:
Как быстро 'dd' может управлять чтением и записать в диск? Пример...
dd if=/dev/zero bs=1024 count=2000000 of=file_2GB
Принятие Вашего диска способно к чтению/записи приблизительно в 40Mb/s (который является, вероятно, реалистическим числом для запуска с), файл на 2 ГБ не может работать быстрее, чем приблизительно 50 секунд.
Сколько времени это на самом деле берет?
Привет Roddy, с помощью fstream метод чтения с файлами на 1,1 ГБ и большими буферами (128,255 или 512 МБ), требуется приблизительно 43-48 секунд и это - то же использование fstream getline (линию за линией). CP занимает почти 2 минуты для копирования файла.
В этом случае, Ваш ограничены аппаратными средствами. CP должно читать и записать и будет искать назад и вперед через поверхность диска как безумный, когда это делает это. Таким образом, это будет (как Вы видите) быть более двух раз настолько же плохим как простой случай 'чтения'.
Для улучшения скорости первой вещью, которую я попробовал бы, является более быстрый жесткий диск или SSD.
Вы не сказали, каков дисковый интерфейс? SATA является в значительной степени самой легкой/самой быстрой опцией. Также (очевидный факт, это...) удостоверяются, что диск находится физически на той же машине, которую выполняет Ваш код, иначе Вы ограничены сетью...
Я также предложил бы файлы с отображенной памятью, но если Вы собираетесь использовать повышение, я думаю повышение:: iostreams:: mapped_file является лучшим соответствием, чем повышение:: межпроцессный.
Возможно, необходимо изучить файлы с отображенной памятью.
Проверьте их в эту библиотеку: Повышение. Межпроцессный
Не используйте новый для выделения буфера как этот:
Попытка: станд.:: вектор <>
unsigned int buffer_size = 64 * 1024 * 1024; // 64 MB for instance.
std::vector<char> data_buffer(buffer_size);
_file->read(&data_buffer[0], buffer_size);
Также прочитайте статью об использовании подчеркивания в идентификаторе names:. Обратите внимание, что Ваш код в порядке, но.
Просто мысль, но избегают использования станд.:: endl, поскольку это вызовет сброс перед буфером, полон. Используйте '\n' вместо этого для новой строки.
Используя getline () может быть неэффективным, потому что строковый буфер, возможно, должен быть изменен несколько раз, поскольку данные добавляются к нему от потокового буфера. Можно сделать это более эффективным путем предварительной калибровки строки:
Также можно установить размер буфера iostreams или к очень большому или к ПУСТОМУ (для освободившего буфер)
// Unbuffered Accesses:
fstream file;
file.rdbuf()->pubsetbuf(NULL,0);
file.open("PLOP");
// Larger Buffer
std::vector<char> buffer(64 * 1024 * 1024);
fstream file;
file.rdbuf()->pubsetbuf(&buffer[0],buffer.size());
file.open("PLOP");
std::string line;
line.reserve(64 * 1024 * 1024);
while(getline(file,line))
{
// Do Stuff.
}
Если бы Вы собираетесь буферизовать файл сами, то я сообщил бы, что некоторое использование тестирования освободило буфер ввод-вывод (setvbuf на файле, что у Вас есть fopened, может выключить буферизацию библиотеки).
В основном, если Вы собираетесь буферизовать себя, Вы хотите отключить буферизацию библиотеки, поскольку она только собирается причинить Вам боль. Я не знаю, существует ли какой-либо способ сделать это для STL ввод-вывод, таким образом, я рекомендую спуститься до C-уровня ввод-вывод.