Если вы хотите умножить на вес & amp; затем разделите их на сумму (равную weighted.mean
функции в R):
df %>%
mutate_at(vars(t1, t2),
list(weights = ~ case_when(. <= 5 ~ 1,
. > 5 & . <= 8 ~ 2,
TRUE ~ 3))) %>%
mutate(rowMeanWeighted = rowSums(.[, 1:2] * .[, 3:4]) / rowSums(.[, 3:4])) %>%
select(-contains("weights"))
Выход:
t1 t2 rowMeanWeighted
1 1 6 4.333333
2 2 6 4.666667
3 4 5 4.500000
4 6 3 5.000000
5 7 3 5.666667
6 9 7 8.200000
Единственные причины я должен был использовать их, при взаимодействии через интерфейс со сторонними библиотеками, которые используют строки стиля C. Могли бы также быть тайные ситуации, где Вы будете использовать строки стиля C по причинам производительности, но как правило, использование методов на строках C++ происходит, вероятно, быстрее из-за встраивания и специализации, и т.д.
можно использовать c_str()
метод во многих случаях при работе с подобными API, но необходимо знать, что символ * возвратился, константа, и Вы не должны изменять строку через тот указатель. В подобных ситуациях можно все еще использовать vector< char> вместо этого, и, по крайней мере, извлеките пользу из более легкого управления памятью.
Олдскульные струны до функции Textbooks, потому что много основных функций все еще ожидают их как аргументы или возвращают их. Кроме того, это дает некоторое понимание глубинной структуры строки в памяти.
Если для функции нужно постоянный строка, я все еще предпочитаю использовать 'символ константы*' (или константа wchar_t*), даже если программа использует станд.:: строка, CString, EString или безотносительно в другом месте.
существует только слишком много источников строк в большой кодовой базе, чтобы быть уверенными, что у вызывающей стороны будет строка как станд.:: строка и 'символ константы*' являются наименьшим общим знаменателем.
Управление памятью. Я недавно должен был обработать строки (на самом деле блобы от базы данных) приблизительно 200-300 МБ в размере в в широком масштабе многопоточном приложении. Это была ситуация, где just-one-more копия строки, возможно, разорвала адресное пространство на 32 бита. Я должен был знать точно, сколько копий строки существовало. Хотя я - евангелист STL, я использовал символ * тогда, потому что он дал мне гарантию, что никакая дополнительная память или даже дополнительная копия не были выделены. Я знал точно, в каком количестве пространства будет требоваться.
Кроме этого, стандартный STL растягивает обработку промахи на некоторых больших функциях C для строковой обработки/парсинга. К счастью, станд.:: строка имеет c_str () метод для доступа константы к внутреннему буферу. Для использования printf (), все еще необходимо использовать символ * хотя (что сумасшедшая идея команды C++ не включать (s) подобную printf функциональность, одну из самых полезных функций КОГДА-ЛИБО в C. Я надеюсь повышение:: формат будет скоро включен в STL.
Скажем, у Вас есть некоторые строковые константы в Вашем коде, который является довольно общей потребностью. Лучше определить их как струны до, чем как объекты C++ - более легкий, портативный, и т.д. Теперь, если Вы собираетесь быть передачей этих строк к различным функциям, хорошо, если эти функции принимают струну до вместо того, чтобы требовать строкового объекта C++.
, Конечно, если строки изменяемы, то намного более удобно использовать строковые объекты C++.
Поскольку это - то, как они происходят из многочисленного API/библиотек?
Пара большей памяти управляет примечаниями:
струны до являются типами POD, таким образом, они могут быть выделены в сегменте данных Вашего приложения только для чтения. Если Вы объявите и определите std::string
константы в объеме пространства имен, то компилятор сгенерирует дополнительный код, который работает прежде main()
, который звонит std::string
конструктор для каждой константы. Если Ваше приложение имеет много постоянных строк (например, если Вы сгенерировали код C++, который использует постоянные строки), струны до могут быть предпочтительными в этой ситуации.
Некоторые реализации std::string
поддерживают функцию под названием SSO ("короткая строковая оптимизация" или "маленькая строковая оптимизация"), где std::string
класс содержит устройство хранения данных для строк до определенной длины. Это увеличивает размер std::string
, но часто значительно уменьшает частоту выделений/освобождения свободного хранилища, улучшая производительность. Если Ваша реализация std::string
не будет поддерживать SSO, то построение пустого std::string
на стеке все еще выполнит выделение свободного хранилища. Если это так, использование временных выделенных стеку струн до может быть полезным для критического по отношению к производительности кода, который использует строки. Конечно, необходимо бояться стрелять себе в ногу, когда Вы делаете это.
Некоторые сообщения упоминают проблемы памяти. Это могло бы быть серьезным основанием избежать станд.:: строка, но символ*, вероятно, не является лучшей заменой. Это - все еще язык OO. Ваш собственный строковый класс, вероятно, лучше, чем char*. Это может даже быть более эффективно - можно применить Маленькую Строковую Оптимизацию, например.
В моем случае, я пытался получить ценность приблизительно на 1 ГБ строк из файла на 2 ГБ, наполнить их в записях приблизительно с 60 полями и затем отсортировать их 7 раз различных полей. Мой код-предшественник занял 25 часов с символом*, мой код работал через 1 час.
Обычная причина сделать это состоит в том, что Вы любите писать переполнение буфера в своей строковой обработке. Считаемые строки так превосходят завершенные строки, которые трудно видеть, почему разработчики C когда-либо использовали завершенные строки. Это было плохое решение затем; это - плохое решение теперь.
1) "строковая константа" является струной до (символ константы *), преобразовывая его в станд. константы:: string& процесс во время выполнения, не обязательно простой или оптимизированный. 2) библиотека fstream использует строки c-стиля для передачи имен файлов.
Мое эмпирическое правило состоит в том, чтобы передать станд. константы:: string& если я собираюсь использовать данные в качестве станд.:: представьте в виде строки так или иначе (скажите, когда я храню их в векторе), и символ константы * в других случаях.
струны до не несут издержки того, чтобы быть классом.
струны до обычно могут приводить к более быстрому коду, поскольку они ближе к Нельзя сказать уровню
машины, Вы не можете написать плохой код с ними. Они могут неправильно использоваться, как любая конструкция.
существует богатство вызовов libary, которые требуют их по историческим причинам.
Учатся использовать струны до и строки stl, и использовать каждого, когда имеет смысл делать так.
Строки STL, конечно, намного легче использовать, и я не вижу оснований для не использования их.
, Если необходимо взаимодействовать с библиотекой, которая только берет строки C-стиля в качестве аргументов, можно всегда называть c_str () методом строкового класса.
Для приложений, таких как самые встроенные платформы, где у Вас нет роскоши "кучи" для хранения строк, управляемых, и где детерминированное предварительное выделение строковых буферов требуется.
Это зависит от библиотек, которыми Вы пользуетесь. Например, при работе с MFC, часто легче использовать CString при работе с различными частями Windows API. Это также, кажется, работает лучше, чем станд.:: строка в приложениях Win32.
Однако станд.:: строка является частью стандарта C++, поэтому если Вы хотите лучшую мобильность, пойдите со станд.:: строка.
После расходов далеко, далеко, слишком много времени, отлаживая инициализацию управляет и каждая мыслимая строковая реализация на нескольких платформах, мы требуем, чтобы статические строки были константой char*.
После расходов далеко, далеко, слишком много времени, отлаживая плохой символ* код и утечки памяти я предполагаю, что все нестатические строки являются некоторым типом строкового объекта... до профилирования шоу, что Вы можете и должны сделать что-то лучше ;-)
Учитывая выбор, обычно нет никакой причины выбрать примитивные струны до (char*
) по строкам C++ (std::string
). Однако часто у Вас нет предпочтительной роскоши. Например, std::fstream
конструкторы берут струны до по историческим причинам. Кроме того, библиотеки C (Вы предположили это!) используют струны до.
В Вашем собственном коде C++ лучше использовать std::string
и извлекать струну до объекта по мере необходимости при помощи c_str()
функция std::string
.
Если код C++ "глубок" (близко к ядру, в большой степени зависит от библиотек C, и т.д.), можно хотеть использовать струны до явно для предотвращения большого количества преобразований в к и из станд.:: строка. Из, если Вы взаимодействуете через интерфейс с другими доменами языка (Python, Ruby, и т.д.) Вы могли бы сделать так по той же причине. Иначе используйте станд.:: строка.