Реструктуризация данных с использованием R
У меня есть набор данных (dat), который выглядит следующим образом:
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 вошел под более чем одним IP-адресом. Когда это происходит, я хочу, чтобы IP-адрес в последнем наборе данных отражал IP-адрес режима - другими словами, IP-адрес, под которым человек входил в систему наиболее часто.
3 ответа
Вот один из подходов.
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
ОБНОВИТЬ
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)
Ты можешь использовать data.table
для краткого решения:
library(data.table)
setDT(dat)
dat[, list(IPaddress=names(which.max(table(IPaddress))),
Logins=.N),
by=Person]
Пытаться:
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