Как отсортировать фрейм данных по нескольким столбцам

Введение

Истеризация потоков из управляемого управляемого сеанса компонента не обязательно является хаком, если она выполняет задание, которое вы хотите. Но нерестовые потоки при необходимости должны выполняться с особой осторожностью. Код не должен записываться таким образом, чтобы один пользователь мог, например, создать неограниченное количество потоков за сеанс и / или продолжить работу потоков даже после того, как сеанс будет уничтожен. Это рано или поздно взорвет ваше приложение.

Код должен быть написан таким образом, чтобы вы могли убедиться, что пользователь может, например, никогда не создавать более одного фонового потока за сеанс и гарантировать поток чтобы прерваться всякий раз, когда сессия будет уничтожена. Для выполнения нескольких задач в сеансе вам необходимо поставить в очередь задачи.

Кроме того, все эти потоки должны предпочтительно обслуживаться общим пулом потоков, чтобы вы могли наложить ограничение на общее количество порожденных потоков на уровне приложения. Средний сервер приложений Java EE предлагает пул потоков, управляемый контейнером, который вы можете использовать, среди прочих, EJB @Asynchronous и @Schedule . Чтобы быть независимым от контейнера, вы также можете использовать Util Concurrent ExecutorService и ScheduledExecutorService для Java 1.5.

Ниже приведены примеры Java EE 6+ с EJB.

Огонь и забыть задачу в форме submit

@Named
@RequestScoped // Or @ViewScoped
public class Bean {

    @EJB
    private SomeService someService;

    public void submit() {
        someService.asyncTask();
        // ... (this code will immediately continue without waiting)
    }

}
@Stateless
public class SomeService {

    @Asynchronous
    public void asyncTask() {
        // ...
    }

}

Асинхронно извлекать модель при загрузке страницы

@Named
@RequestScoped // Or @ViewScoped
public class Bean {

    private Future> asyncEntities;

    @EJB
    private EntityService entityService;

    @PostConstruct
    public void init() {
        asyncEntities = entityService.asyncList();
        // ... (this code will immediately continue without waiting)
    }

    public List getEntities() {
        try {
            return asyncEntities.get();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new FacesException(e);
        } catch (ExecutionException e) {
            throw new FacesException(e);
        }
    }
}
@Stateless
public class EntityService {

    @PersistenceContext
    private EntityManager entityManager;

    @Asynchronous
    public Future> asyncList() {
        List entities = entityManager
            .createQuery("SELECT e FROM Entity e", Entity.class)
            .getResultList();
        return new AsyncResult<>(entities);
    }

}

Если вы используете библиотечную утилиту JSF OmniFaces , это можно сделать еще быстрее, если вы аннотируете управляемый компонент с помощью @Eager .

Расписание фоновых заданий при запуске приложения

@Singleton
public class BackgroundJobManager {

    @Schedule(hour="0", minute="0", second="0", persistent=false)
    public void someDailyJob() {
        // ... (runs every start of day)
    }

    @Schedule(hour="*/1", minute="0", second="0", persistent=false)
    public void someHourlyJob() {
        // ... (runs every hour of day)
    }

    @Schedule(hour="*", minute="*/15", second="0", persistent=false)
    public void someQuarterlyJob() {
        // ... (runs every 15th minute of hour)
    }

    @Schedule(hour="*", minute="*", second="*/30", persistent=false)
    public void someHalfminutelyJob() {
        // ... (runs every 30th second of minute)
    }

}

Непрерывно обновлять модель приложения в фоновом режиме

@Named
@RequestScoped // Or @ViewScoped
public class Bean {

    @EJB
    private SomeTop100Manager someTop100Manager;

    public List getSomeTop100() {
        return someTop100Manager.list();
    }

}
@Singleton
@ConcurrencyManagement(BEAN)
public class SomeTop100Manager {

    @PersistenceContext
    private EntityManager entityManager;

    private List top100;

    @PostConstruct
    @Schedule(hour="*", minute="*/1", second="0", persistent=false)
    public void load() {
        top100 = entityManager
            .createNamedQuery("Some.top100", Some.class)
            .getResultList();
    }

    public List list() {
        return top100;
    }

}

См. также:

1237
задан NelsonGon 3 April 2019 в 16:37
поделиться

5 ответов

Вы можете использовать функцию order () напрямую, не прибегая к дополнительным инструментам - см. Этот более простой ответ, в котором используется трюк прямо из верхней части ] пример (порядок) код:

R> dd[with(dd, order(-z, b)), ]
    b x y z
4 Low C 9 2
2 Med D 3 1
1  Hi A 8 1
3  Hi A 9 1

Редактировать через 2+ года: Просто спросили, как это сделать по индексу столбца. Ответ состоит в том, чтобы просто передать желаемый столбец сортировки в функцию order () :

R> dd[order(-dd[,4], dd[,1]), ]
    b x y z
4 Low C 9 2
2 Med D 3 1
1  Hi A 8 1
3  Hi A 9 1
R> 

, а не использовать имя столбца (и с () для упрощения / более прямой доступ).

1580
ответ дан 19 December 2019 в 20:14
поделиться

В качестве альтернативы, используя пакет Deducer

library(Deducer)
dd<- sortData(dd,c("z","b"),increasing= c(FALSE,TRUE))
27
ответ дан 19 December 2019 в 20:14
поделиться

С помощью этой (очень полезной) функции Кевина Райта , размещенной в разделе советов вики-сайта R, этого легко добиться.

sort(dd,by = ~ -z + b)
#     b x y z
# 4 Low C 9 2
# 2 Med D 3 1
# 1  Hi A 8 1
# 3  Hi A 9 1
69
ответ дан 19 December 2019 в 20:14
поделиться

Или вы можете использовать пакет доб

library(doBy)
dd <- orderBy(~-z+b, data=dd)
35
ответ дан 19 December 2019 в 20:14
поделиться

если SQL для вас естественен, sqldf пакет обрабатывает ORDER BY как и предполагал Кодд.

29
ответ дан 19 December 2019 в 20:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: