0

This is probably a simple question for ppl better at dplyr - I'd like to compute a frequency list of character data in a dataframe:

Toy data:

df <- data.frame(
  id = sample(1:5, 100, replace = TRUE),
  v1 = sample(c(NA, rnorm(10)), 100, replace = TRUE),
  v2 = sample(LETTERS, 100, replace = TRUE)
)

My attempt so far:

Let's assume the df first needs to be filtered for a number of variables. Once done with that I am able to compute the frequency list but the output does not show the respective character values so I don't know which value has which frequency:

library(dplyr)
df %>%
  filter(!is.na(v1) & !id == lag(id)) %>%
  summarise(freq = sort(prop.table(table(v2)), decreasing = TRUE)*100)
       freq
1  7.692308
2  6.410256
3  5.128205
4  5.128205
5  5.128205
6  5.128205
7  5.128205
8  5.128205
9  5.128205
10 5.128205
output clipped ...

So what I need to get is a second column showing the value A, B, C etc. that the frequencies belong to. How can that be achieved?

EDIT:

Ooops I think I got it:

df %>%
  filter(!is.na(v1) & !id == lag(id)) %>%
  summarise(freq = sort(prop.table(table(v2)), decreasing = TRUE)*100,
            value = names(sort(prop.table(table(v2)), decreasing = TRUE)))
Chris Ruehlemann
  • 20,321
  • 4
  • 12
  • 34

3 Answers3

2

More dplyr - way would be :

library(dplyr)

df %>%
  filter(!is.na(v1) & id != lag(id)) %>%
  count(v2, name = 'freq', sort = TRUE) %>%
  mutate(freq = prop.table(freq) * 100)

#   v2     freq
#1   M 9.090909
#2   Q 7.792208
#3   K 6.493506
#4   R 6.493506
#5   T 6.493506
#6   B 5.194805
#7   C 5.194805
#8   F 5.194805
#9   I 5.194805
#10  U 5.194805
#11  G 3.896104
#12  J 3.896104
#13  S 3.896104
#14  V 3.896104
#15  W 3.896104
#16  A 2.597403
#17  N 2.597403
#18  X 2.597403
#19  D 1.298701
#20  E 1.298701
#21  H 1.298701
#22  L 1.298701
#23  O 1.298701
#24  P 1.298701
#25  Y 1.298701
#26  Z 1.298701
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
2
df %>%
  filter(!is.na(v1) & !id == lag(id)) %>% 
  mutate(n_total = n()) %>% 
  group_by(v2) %>% 
  summarise(freq = n(), n_total = max(n_total)) %>% 
  mutate(freq = 100*freq/n_total) %>% 
  select(-n_total) %>% 
  arrange(-freq)
  
Mouad_Seridi
  • 2,666
  • 15
  • 27
0

More dplyr with a bit of janitor:

library(janitor)

df %>%
  filter(!is.na(v1) & !id == lag(id)) %>%
  tabyl(v2) %>%
  rename(freq = percent) %>%
  mutate(freq = freq * 100) %>%
  select(-n) %>%
  arrange(desc(freq))


 v2     freq
  M 8.641975
  W 7.407407
  A 6.172840
  K 6.172840
  N 6.172840
  U 6.172840
  G 4.938272
  S 4.938272
  T 4.938272
  Y 4.938272
  D 3.703704
  F 3.703704
  H 3.703704
  J 3.703704
  P 3.703704
  V 3.703704
  C 2.469136
  L 2.469136
  O 2.469136
  Q 2.469136
  X 2.469136
  E 1.234568
  I 1.234568
  R 1.234568
  Z 1.234568

Anoushiravan R
  • 21,622
  • 3
  • 18
  • 41