2014-10-14 22 views
1

У меня есть набор данных (DAT), который выглядит следующим образом:данных реструктуризации с использованием R

Person  IPaddress 
36598035 222.999.22.99 
36598035 222.999.22.99 
36598035 222.999.22.99 
36598035 222.999.22.99 
36598035 222.999.22.99 
36598035 444.666.44.66 
37811171 111.88.111.88 
37811171 111.88.111.88 
37811171 111.88.111.88 
37811171 111.88.111.88 
37811171 111.88.111.88 

Это отражает случаи, что люди зашли на веб-сайт в течение определенного периода времени. Мне нужны данные, чтобы выглядеть следующим образом:.

Person  IPaddress  Number of Logins 
36598035 222.999.22.99   6 
37811171 111.88.111.88   5 

Таким образом, вместо нескольких записей для одного человека, есть только одна строки на одного человека, с подсчетом, сколько раз они вошли в

Кроме того, вы увидите в моем примере, что человек 36598035 вошел в систему под более чем 1 IP-адресом. Когда это произойдет, я хочу, чтобы IP-адрес в конечном наборе данных отражал IP-адрес режима, другими словами, IP-адрес, который пользователь регистрировал чаще всего.

+0

@ waxattax: количество входов должно быть 5,5, а не 6,5 – rnso

+0

@rnso нет, я думаю, что вы искажая вопрос. – shadowtalker

+0

@mso На самом деле, человек 36598035 сделал вход в систему 6 раз, только с двух разных IP-адресов. Я хотел бы сохранить тот факт, что человек регистрировался в 6 раз, независимо от того, с какого IP-адреса он/она вошел. Спасибо за вашу помощь! :) – waxattax

ответ

5

Вот один подход.

library(dplyr) 

mydf %>% 
    group_by(Person, IPaddress) %>% # For each combination of person and IPaddress 
    summarize(freq = n()) %>% # Get total number of log-in 
    arrange(Person, desc(freq)) %>% # The most frequent IP address is in the 1st row for each user 
    group_by(Person) %>% # For each user 
    mutate(total = sum(freq)) %>% # Get total number of log-in 
    select(-freq) %>% # Remove count 
    do(head(.,1)) # Take the first row for each user 

# Person  IPaddress total 
#1 36598035 222.999.22.99  6 
#2 37811171 111.88.111.88  5 

UPDATE

dplyr 0,3 является сейчас. Таким образом, вы могли бы сделать следующее. Только одна строка короче, используя count. Я также использовал slice как @aosmith.

mydf %>% 
    count(Person, IPaddress) %>% 
    arrange(Person, desc(n)) %>% 
    group_by(Person) %>% 
    mutate(total = sum(n)) %>% 
    select(-n) %>% 
    slice(1) 
+0

Вы еще не исследовали' slice'? Вы можете использовать его вместо строки 'do' (' slice (1) '). – aosmith

+0

@aosmith Спасибо за примечание. Я видел несколько пользователей, использующих 'slice'. Сейчас я буду играть с ним. Вы заметили какие-либо другие изменения в 0,3? Я хотел бы знать, устарели ли какие-либо функции в 0,3. @akrun любезно упомянул, что 'summaryise_each_q' устарел. Итак, 'mutate_each_q'. – jazzurro

+0

Есть еще несколько новых вещей. Просто ознакомьтесь с новостями для каждой версии [здесь] (https://github.com/hadley/dplyr/blob/master/NEWS.md) – aosmith

1

Try:

ddf 
    Person  IPaddress 
1 36598035 222.999.22.99 
2 36598035 222.999.22.99 
3 36598035 222.999.22.99 
4 36598035 222.999.22.99 
5 36598035 222.999.22.99 
6 36598035 444.666.44.66 
7 37811171 111.88.111.88 
8 37811171 111.88.111.88 
9 37811171 111.88.111.88 
10 37811171 111.88.111.88 
11 37811171 111.88.111.88 

dd1 = data.table(with(ddf, table(Person, IPaddress)))[rev(order(N))][!duplicated(Person)] 
dd1 
    Person  IPaddress N 
1: 36598035 222.999.22.99 5 
2: 37811171 111.88.111.88 5 

dd1$all_login_count = data.table(with(ddf, table(Person)))$V1 
dd1 
    Person  IPaddress N all_login_count 
1: 36598035 222.999.22.99 5    6 
2: 37811171 111.88.111.88 5    5 
+0

Это исключает менее распространенный IP-адрес, который не является тем, о чём задан вопрос. – shadowtalker

+1

В нем показано, что задано: «IP-адрес, который пользователь регистрировал чаще всего». – rnso

+0

* Счет * должен включать * все * IP-адреса. Указанный IP-адрес должен быть наиболее частым. Посмотрите на пример в сообщении. – shadowtalker

4

Вы можете использовать data.table для краткого решения:

library(data.table) 
setDT(dat) 
dat[, list(IPaddress=names(which.max(table(IPaddress))), 
      Logins=.N), 
    by=Person] 
+1

Это действительно лаконично! Сейчас я изучаю data.table. Спасибо, что разделили эту идею. – jazzurro

Смежные вопросы