Во-первых, две альтернативы base
. Один полагается на table
, а другой на ave
и length
. Затем два пути data.table
.
table
tt <- table(df$name)
df2 <- subset(df, name %in% names(tt[tt < 3]))
# or
df2 <- df[df$name %in% names(tt[tt < 3]), ]
Если вы хотите шаг за шагом пройти:
# count each 'name', assign result to an object 'tt'
tt <- table(df$name)
# which 'name' in 'tt' occur more than three times?
# Result is a logical vector that can be used to subset the table 'tt'
tt < 3
# from the table, select 'name' that occur < 3 times
tt[tt < 3]
# ...their names
names(tt[tt < 3])
# rows of 'name' in the data frame that matches "the < 3 names"
# the result is a logical vector that can be used to subset the data frame 'df'
df$name %in% names(tt[tt < 3])
# subset data frame by a logical vector
# 'TRUE' rows are kept, 'FALSE' rows are removed.
# assign the result to a data frame with a new name
df2 <- subset(df, name %in% names(tt[tt < 3]))
# or
df2 <- df[df$name %in% names(tt[tt < 3]), ]
ave
и length
Как предложено @flodel:
df[ave(df$x, df$name, FUN = length) < 3, ]
data.table
: .N
и .SD
: library(data.table)
setDT(df)[, if (.N < 3) .SD, by = name]
data.table
: .N
и .I
: setDT(df)
df[df[, .I[.N < 3], name]$V1]
См. также соответствующий Q & amp; A Рассчитайте количество наблюдений / строк на группу и добавьте результат в кадр данных .
Если вы хотите запустить системные команды через PHP, посмотрите документацию exec .
Я бы не рекомендовал делать это на сайте с высоким трафиком, процесс для каждого запроса является довольно сложным процессом. Некоторые программы предоставляют возможность записывать свой идентификатор процесса в файл, который вы могли бы проверить, и завершать процесс по своему усмотрению, но для таких команд, как ping, я не уверен, что это возможно, проверьте страницы man.
Вам может быть лучше обслуживать, просто открыв сокет на порту, который вы ожидаете слушать (IE: порт 80 для HTTP) на удаленном хосте, таким образом вы знаете, что все идет хорошо в пользовательской области, а также на network.
Если вы пытаетесь вывести двоичные данные в функцию заголовка php и убедитесь, что вы задали правильный тип содержимого и Content-Disposition . Просмотрите документацию для получения дополнительной информации об использовании / отключении выходного буфера.
Я пробовал различные команды выполнения PHP в Windows и обнаружил, что они сильно различаются.
shell_exec
, exec
, passthru
proc_open
, popen
- «вид», потому что вы не можете передавать аргументы своей команде (т. е. не работать с my.exe --something
, будет работать с _my_something.bat
). Наилучший (самый простой) подход:
header('Content-Type: text/event-stream');
(вместо header('Content-Type: text/plain; charset=...');
). Однако это не будет работать во всех браузерах / клиентах! Потоковая передача будет работать без этого, но по крайней мере первые строки будут буферизованы браузером. header('Cache-Control: no-cache');
. ini_set('output_buffering', 'off');
). Это также может быть сделано в Apache / Nginx / любом сервере, который вы используете спереди. ini_set('zlib.output_compression', false);
). Это также может быть сделано в Apache / Nginx / любом сервере, который вы используете спереди. Итак, в вашей программе на C ++ вы делаете что-то вроде этого (опять же, для других решений см. printf проблема с промывкой ):
Logger::log(...) {
printf (text);
fflush(stdout);
}
В PHP вы делаете что-то вроде:
function setupStreaming() {
// Turn off output buffering
ini_set('output_buffering', 'off');
// Turn off PHP output compression
ini_set('zlib.output_compression', false);
// Disable Apache output buffering/compression
if (function_exists('apache_setenv')) {
apache_setenv('no-gzip', '1');
apache_setenv('dont-vary', '1');
}
}
function runStreamingCommand($cmd){
echo "\nrunning $cmd\n";
system($cmd);
}
...
setupStreaming();
runStreamingCommand($cmd);
почему бы просто не подключить вывод в файл журнала, а затем использовать этот файл для возврата содержимого клиенту. не совсем в режиме реального времени, но, возможно, достаточно хорошо?
Для использования в командной строке:
function execute($cmd) {
$proc = proc_open($cmd, [['pipe','r'],['pipe','w'],['pipe','w']], $pipes);
while(($line = fgets($pipes[1])) !== false) {
fwrite(STDOUT,$line);
}
while(($line = fgets($pipes[2])) !== false) {
fwrite(STDERR,$line);
}
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
return proc_close($proc);
}
Если вы пытаетесь запустить файл, вам может потребоваться сначала предоставить разрешения на выполнение:
chmod('/path/to/script',0755);
Это хороший способ показать вывод команд вашей оболочки в реальном времени:
<?php
header("Content-type: text/plain");
// tell php to automatically flush after every output
// including lines of output produced by shell commands
disable_ob();
$command = 'rsync -avz /your/directory1 /your/directory2';
system($command);
Эта функция понадобится для предотвращения буферизации вывода:
function disable_ob() {
// Turn off output buffering
ini_set('output_buffering', 'off');
// Turn off PHP output compression
ini_set('zlib.output_compression', false);
// Implicitly flush the buffer(s)
ini_set('implicit_flush', true);
ob_implicit_flush(true);
// Clear, and turn off output buffering
while (ob_get_level() > 0) {
// Get the curent level
$level = ob_get_level();
// End the buffering
ob_end_clean();
// If the current level has not changed, abort
if (ob_get_level() == $level) break;
}
// Disable apache output buffering/compression
if (function_exists('apache_setenv')) {
apache_setenv('no-gzip', '1');
apache_setenv('dont-vary', '1');
}
}
Это doesn я работаю на каждом сервере, на котором я его пробовал, хотя хотел бы посоветовать, что искать в вашей php-конфигурации, чтобы определить, нужно ли вам вытаскивать волосы, пытаясь заставить этот тип поведения работать на вашем сервер! Кто-нибудь еще знает?
Вот фиктивный пример в простом PHP:
<?php
header("Content-type: text/plain");
disable_ob();
for($i=0;$i<10;$i++)
{
echo $i . "\n";
usleep(300000);
}
Надеюсь, это поможет другим людям, которые отправились туда по пути.
ob_implicit_flush(true);ob_end_flush();
в начале
– tetris11
27 September 2012 в 15:15
shell_exec
. Хорошо работает, если вы просто хотите показать результат и не обрабатывать его.
– jxmallett
16 January 2015 в 07:58
header('X-Content-Type-Options: nosniff');
– Jack Sleight
16 November 2016 в 17:13
for ($i=0; $i < 100000; $i++) { echo " "; } echo "\n"; flush();
– Martin Pecka
11 August 2017 в 09:24
попробуйте это (протестировано на машине Windows + wamp server)
header('Content-Encoding: none;');
set_time_limit(0);
$handle = popen("<<< Your Shell Command >>>", "r");
if (ob_get_level() == 0)
ob_start();
while(!feof($handle)) {
$buffer = fgets($handle);
$buffer = trim(htmlspecialchars($buffer));
echo $buffer . "<br />";
echo str_pad('', 4096);
ob_flush();
flush();
sleep(1);
}
pclose($handle);
ob_end_flush();
Более эффективное решение этой старой проблемы с использованием современных событий на стороне сервера HTML5 описано здесь:
http://www.w3schools.com/html/html5_serversentevents.asp
Пример:
http://sink.agiletoolkit.org/realtime/console
Код: https://github.com/atk4/sink/blob/master/admin/page/realtime/console.php#L40
(Реализовано как модуль в инфраструктуре Agile Toolkit)
Сначала проверьте, работает ли flush () . Если это так, хорошо, если это не так, вероятно, означает, что веб-сервер по какой-то причине буферизуется, например mod_gzip включен.
Для чего-то вроде ping самым простым методом является цикл внутри PHP, запускать «ping -c 1» несколько раз и вызывать flush () после каждого выхода. Предполагая, что PHP настроен на отмену, когда HTTP-соединение закрывается пользователем (обычно это значение по умолчанию, или вы можете вызвать ignore_user_abort (false), чтобы убедиться), тогда вам не нужно беспокоиться о запущенных процессах ping либо .
Если действительно необходимо, чтобы вы только выполняли дочерний процесс один раз и непрерывно отображали его вывод, что может быть сложнее - вам, вероятно, придется запускать его в фоном, перенаправлять вывод в поток, а затем PHP-эхо-поток, возвращаемый пользователю, чередующийся с регулярными вызовами flush ().
Попробуйте изменить набор файлов php.ini «output_buffering = Off». Вы должны иметь возможность получить вывод в реальном времени на странице. Использовать системную команду вместо команды exec .. system будет очищать вывод
Проверено все ответы, ничего не работает ...
Найдено решение Здесь
Он работает на окнах (я думаю, что этот ответ полезен для поиска пользователей там)
<?php
$a = popen('ping www.google.com', 'r');
while($b = fgets($a, 2048)) {
echo $b."<br>\n";
ob_flush();flush();
}
pclose($a);
?>