Группируйте данные в соответствии с различными последовательностями чисел - считайте конкретные перестановки, представляющие интерес - PullRequest
0 голосов
/ 04 декабря 2018

Меня интересуют четыре последовательности чисел:

Clockwise
1->2
2->3
3->4
4->1

Counterclockwise
1->4
4->3
3->2
2->1

Opposite
1->3
3->1
2->4
4->2

Repeat
1->1
2->2
3->3
4->4

Я хочу подсчитать, сколько раз каждая из этих групп последовательностей встречается в столбце Choice моих данных для каждого Person.

Вот мои данные:

df <- structure(list(Time = 1:28, Person = c(1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L), Choice = c(1L, 2L, 1L, 2L, 1L, 1L, 3L, 
4L, 1L, 4L, 4L, 1L, 1L, 1L, 4L, 4L, 3L, 4L, 1L, 4L, 2L, 3L, 1L, 
4L, 4L, 1L, 1L, 4L)), class = "data.frame", row.names = c(NA, 
-28L))

enter image description here

В этом наборе данных, глядя на строку 1 -> строку 2считается Clockwise, поэтому один счет добавляется к Clockwise для персоны 1. строка 2 -> строка 3 равна Counterclockwise и т. д.

Как можно добиться этого без записи if-else для каждогои все условия?

Ожидаемый результат

enter image description here

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

Вот моя попытка: также с использованием функций ?diff и base::.

ans <- c(NA, diff(df$Choice))
ans[ans %in% c(1,-3)] <- "cw"; ans[ans %in% c(-1,3)] <- "ccw"; ans[ans  %in% 0] <- "rep"; ans[ans %in% c(-2,2)] <- "op"

df$result <- ans

tapply(df$result, df$Person, table)

результаты:

#   Time Person Choice result
#1     1      1      1   <NA>
#2     2      1      2     cw
#3     3      1      1    ccw
#4     4      1      2     cw
#5     5      1      1    ccw
#6     6      1      1    rep
#7     7      1      3     op
#8     8      1      4     cw
#9     9      1      1     cw
#10   10      1      4    ccw
#11   11      1      4    rep
#12   12      1      1     cw
#13   13      1      1    rep
#14   14      1      1    rep
#15   15      2      4    ccw
#16   16      2      4    rep
#17   17      2      3    ccw
#18   18      2      4     cw
#19   19      2      1     cw
#20   20      2      4    ccw
#21   21      2      2     op
#22   22      2      3     cw
#23   23      2      1     op
#24   24      2      4    ccw
#25   25      2      4    rep
#26   26      2      1     cw
#27   27      2      1    rep
#28   28      2      4    ccw

и:

#$`1`    <- person 1
#
#ccw  cw  op rep 
#  3   5   1   4
#
#$`2`    <- person 2
#
#ccw  cw  op rep 
#  5   4   2   3 
0 голосов
/ 04 декабря 2018

Вы можете использовать diff, чтобы получить разницу последовательных строк.Каждая из ваших категорий соответствует конкретному случаю diff(Choice) %% 4.0 = «Повторить», 1 = «По часовой стрелке», 2 = «Противоположно», 3 = «Против часовой стрелки».Затем вы можете классифицировать его по категориям, используя cut:

Редактировать: я изменил код, чтобы он соответствовал желаемому выводу

df %>%
  group_by(Person) %>%
  mutate(Sequence=
           c(diff(Choice) %% 4,NA) %>%
           cut(breaks=4,labels = c('Repeat','Clockwise','Opposite','Counterclockwise'))
         ) %>% 
  filter(!is.na(Sequence)) %>%
  group_by(Person,Sequence)%>%
  summarise(Count=n())

# # A tibble: 8 x 3
# # Groups:   Person [?]
# Person Sequence         Count
# <int> <fct>            <int>
#   1      1 Repeat               4
# 2      1 Clockwise            5
# 3      1 Opposite             1
# 4      1 Counterclockwise     3
# 5      2 Repeat               3
# 6      2 Clockwise            4
# 7      2 Opposite             2
# 8      2 Counterclockwise     4
...