Агрегирование строк на основе строк в разном порядке

У меня есть набор данных, образец которого может быть представлен ниже:

    ORIGIN <- c("SFO", "BOS", "LAX", "BOS")
    DEST <- c("BOS", "SFO", "BOS", "LAX")
    PASS<- c(100,50,20,40)
    df = data.frame(ORIGIN, DEST, ROUTE, PASS)

ORIGIN DEST    PASS
SFO    BOS     100
BOS    SFO     50
LAX    BOS     20
BOS    LAX     40

Я пытаюсь объединить ORIGIN и DEST вместе, чтобы сформировать ROUTE, а затем агрегировать строки по маршруту, независимо от пункта отправления или назначения, чтобы получить общее количество пассажиров.

В идеале я хотел бы следующее:

ROUTE    PASS
SFO-BOS  150
LAX-BOS  60

Меня не волнует, какая метрика именования маршрутов преобладает, пока я могу их комбинировать.

В качестве первого шага я использовал это:

df$ROUTE<-paste(df$ORIGIN, df$DEST, sep="-")

Чтобы получить следующее:

ORIGIN DEST   ROUTE    PASS
SFO    BOS    SFO-BOS  100
BOS    SFO    BOS-SFO  50
LAX    BOS    LAX-BOS  20
BOS    LAX    BOS-LAX  40

Однако, хотя я обычно использую что-то вроде ddply для получения суммы пассажиров, я не знаю, как действовать, поскольку пытаюсь объединить «BOS-SFO» и «SFO-BOS».

Это не было бы проблемой в маленьком файле, но файл, с которым я работаю, слишком велик.

Кто-нибудь сможет помочь?


person Martin Jones    schedule 07.02.2017    source источник
comment
Релевантно - stackoverflow.com/questions/35834385/ или stackoverflow.com/questions/25297812/ или stackoverflow.com/questions/25145982/   -  person thelatemail    schedule 08.02.2017
comment
Ваш paste() еще может работать, но сначала нужно отсортировать маршрут, paste(apply(df[,1:2],1,max),apply(df[,1:2],1,min),sep="-") потом можно просто агрегировать по маршруту aggregate(PASS ~ ROUTE, data=df, sum)   -  person gsun    schedule 08.02.2017


Ответы (2)


Для этого предназначены pmax и pmin. Использование dplyr:

df %>% 
  mutate(start = pmin(ORIGIN, DEST),
         end = pmax(ORIGIN, DEST)) %>% 
  group_by(start, end) %>% 
  summarize(PASS = sum(PASS))

#  start   end  PASS
# 1   BOS   LAX    60
# 2   BOS   SFO   150
person GGamba    schedule 07.02.2017
comment
Ага. Базовый перевод - df$ROUTE <- interaction(do.call(pmin, lapply(df[c("ORIGIN","DEST")],as.character)), do.call(pmax, lapply(df[c("ORIGIN","DEST")],as.character))) и aggregate(PASS ~ ROUTE, data=df, sum) - person thelatemail; 08.02.2017

Используя mapply в базе R для объединения результатов,

# sort each pair of dest and origin by row and paste results.
df$ROUTE <- mapply(function(x, y) paste(sort(c(x, y)), collapse="-"),
                   df$ORIGIN, df$DEST, USE.NAMES=FALSE)

aggregate(PASS ~ ROUTE, data=df, sum)
    ROUTE PASS
1 BOS-LAX   60
2 BOS-SFO  150

данные

Обратите внимание, что этот метод требует работы с символьными переменными, а не факторными переменными. Data.frame, df, строится, как показано ниже.

df = data.frame(ORIGIN, DEST, PASS, stringsAsFactors=FALSE)
person lmo    schedule 08.02.2017