У меня была та же проблема, но я искал решение, которое работает с трубой (%>%
). Использование tidyr::spread
и tidyr::gather
из tidyverse
делает трюк. Я использую те же данные, что и @Brian Diggs, но с именами переменных верхнего регистра, которые не имеют двойных имен переменных при преобразовании в wide:
library(tidyverse)
dat <- data.frame(A = rep(LETTERS[1:3], 3),
B = rep(letters[1:3], each = 3),
V = 1:9)[-2, ]
dat %>%
spread(key = B, value = V, fill = NA) %>% # turn data to wide, using fill = NA to generate missing values
gather(key = B, value = V, -A) %>% # go back to long, with the missings
ggplot(aes(x = A, y = V, fill = B)) +
geom_col(position = position_dodge())
Edit:
еще более простое решение этой проблемы в сочетании с трубой. Использовать tidyr::complete
дает тот же результат в одной строке:
dat %>%
complete(A, B) %>%
ggplot(aes(x = A, y = V, fill = B)) +
geom_col(position = position_dodge())
Для C оптимизированы C++, C#, Java и другие булевы выражения языков.NET так, чтобы, как только достаточно известно, ничто иное не было оценено.
Старый прием для того, чтобы сделать запутываемый код должен был использовать это, чтобы создать если операторы, такие как:
a || b();
если "a" верен, "b ()" никогда не оценивался бы, таким образом, мы можем переписать его в:
if(!a)
b();
и так же:
a && b();
стал бы
if(a)
b();
Обратите внимание на то, что это только допустимо для || и && оператор. Эти два оператора | и и являются побитовыми или, и и, соответственно, и поэтому не "оптимизированы".
Править: Как упомянуто другими, пытаясь оптимизировать код с помощью логики короткого замыкания очень редко хорошо проведенное время.
Сначала пойдите для ясности, и потому что легче читать и понять. Кроме того, при попытке быть слишком умным простым переупорядочением условий, мог бы привести к дико другому поведению без любой очевидной причины.
Во-вторых, пойдите для оптимизации, но только после синхронизации и профилирования. Слишком многие разработчик делают преждевременную оптимизацию без профилирования. Большую часть времени это абсолютно бесполезно.
В соответствии с этой статьей PHP действительно срывает оценку, что означает, что, если первое условие соблюдают, второе даже не оценено. Довольно легко протестировать также (от статьи):
<?php
/* ch06ex07 – shows no output because of short circuit evaluation */
if (true || $intVal = 5) // short circuits after true
{
echo $intVal; // will be empty because the assignment never took place
}
?>
В значительной степени каждый язык делает оценку короткого замыкания. Значение второго условия только оценено, если это aboslutely необходимый для. Чтобы это работало, большинство языков использует двойной канал, ||, не единственный, |.
В C, C++ и Java, операторе:
if (condition1 | condition2) {
...
}
оценит оба условия каждый раз и только будет верен, если все выражение будет верно.
Оператор:
if (condition1 || condition2) {
...
}
оценит condition2
только если condition1
ложь. Разница является значительной, если condition2 является функцией или другим выражением с побочным эффектом.
Нет, однако, никакого различия между ||
случай и if
/else
случай.
Замыкание накоротко не для оптимизации. Это - основная цель, должен избежать кода вызова, который не будет работать, все же приводить к читаемому тесту. Пример:
if (i < array.size() && array[i]==foo) ...
Обратите внимание, что выстраивают [я] могу получить нарушение прав доступа, если я вне диапазона, и разрушьте программу. Таким образом эта программа, конечно, в зависимости от замыкания накоротко оценки!
Я полагаю, что это - причина записи выражений этого пути намного чаще, чем проблемы оптимизации.
Я видел много этих типов вопросов в последнее время - оптимизация до энного градуса.
Я думаю, что это имеет смысл при определенных обстоятельствах:
В других случаях, вызывающих беспокойство о "самом быстром" способе выполнить итерации или проверить условное выражение, глупо. Вместо того, чтобы писать тесты, которые требуют, чтобы миллионы пробных версий видели любого записываемого (но незначительный) различие, внимание на ясность.
Когда кто-то еще (могли быть Вы!) забирает этот код за месяц или год, что будет самым важным, ясность.
В этом случае Ваш первый пример короче, более ясен и не требует, чтобы Вы повторили себя.
В то время как использование закорачивающий в целях оптимизации часто является излишеством, существуют, конечно, другие неопровержимые доводы для использования его. Один такой пример (в C++) следующий:
if( pObj != NULL && *pObj == "username" ) {
// Do something...
}
Здесь, на замыкание накоротко полагаются для обеспечения этого pObj
был выделен до разыменования его. Это намного более кратко, чем то, что вложило if
операторы.
|
побитовый оператор в PHP. Это не означает $a OR $b
, точно. Вы захотите использовать двойной канал. И да, как упомянуто, PHP действительно закорачивает оценку. Точно так же, если первое условие &&
пункт оценивает ко лжи, PHP не оценивает остальную часть пункта, также.
Так как это - отмеченный агностик языка, в которого я вмешаюсь. Для Perl, по крайней мере, первая опция достаточна, я не знаком с PHP. Это оценивает слева направо и выбывает, как только условие соблюдают.
На большинстве языков с достойной оптимизацией первый будет работать просто великолепно.
VB.net имеет два замечательных выражения под названием "OrElse" и "AndAlso"
OrElse сорвет себя в первый раз, когда он достигает Истинной оценки, и выполните код, которого Вы требуете.
If FirstName = "Luke" OrElse FirstName = "Darth" Then
Console.Writeline "Greetings Exalted One!"
End If
AndAlso сорвет себя в первый раз это Ложная оценка и не оценит код в блоке.
If FirstName = "Luke" AndAlso LastName = "Skywalker" Then
Console.Writeline "You are the one and only."
End If
Я нахожу оба из них полезными.