3

Consider this example:

library(dplyr)
library(sf)
library(tmap)

d <- data_frame(one = c(1,1,2,1,1,1,1),
                two = c(1,1,2,1,1,1,1))

std <- st_as_sf(d, coords = c('one', 'two'))

std %>% tm_shape() + tm_bubbles(alpha = 0.3)

enter image description here

You can see that point (1, 1) is darker because it appears 6 times in the data. Therefore, thanks to the alpha blending, these points add-up.

My problem is that I cannot store the dataset as it. What I have is only an aggregated version, like

d_agg <- d %>% group_by(one, two) %>% 
  summarize(count = n()) %>% 
  ungroup()

# A tibble: 2 x 3
    one   two count
  <dbl> <dbl> <int>
1     1     1     6
2     2     2     1

How can I reproduce the same exact chart as before, using d_agg and the corresponding count variable?

Of course, re-creating the initial dataframe above is not feasible solution because I have too many points (and some points are repeated too many times)

Just using:

std_agg %>% tm_shape() + tm_bubbles(col = 'count', alpha = 0.3)

does not work

enter image description here

ℕʘʘḆḽḘ
  • 18,566
  • 34
  • 128
  • 235
  • Please add the packages you used in your code as well – Tung Jun 14 '18 at 19:41
  • 1
    You could recreate the original dataframe using `rep` rows n times? – zx8754 Jun 14 '18 at 19:42
  • 2
    no, that would be way too big. this is the issue. – ℕʘʘḆḽḘ Jun 14 '18 at 19:43
  • 1
    I was thinking maybe you can assign `count == 1` with `grey100` then subtract `100` depending on `count` to create a darker color` e.g. `color <- ifelse(count == 1, "grey100", paste0("grey", (100 - count + 1)))` – Tung Jun 14 '18 at 20:00
  • 1
    I don't know enough `sf/tmap` package to give a full answer. I am thinking, it must be possible take agg data row by row, expand then plot into variable (list), then keep appending following rows. At the end plot that list. This way we will only expand the data per group, not for all groups at once. – zx8754 Jun 14 '18 at 21:10
  • @Tung perhaps that is a good idea. However, count can take very large values as well) – ℕʘʘḆḽḘ Jun 14 '18 at 21:13

2 Answers2

3

Unfortunately, alpha is not (yet) an aesthetic, so it is not possible to do alpha = "count".

My question: do you really need alpha? Probably not if you do not use the color aesthetic. In that case, your approach to use color to model alpha transparency was actually good, but just needs a little configuration:

std_agg %>% tm_shape() + tm_bubbles(col = 'count', style = "cont", 
    palette =  "Greys", contrast = c(.3, .7), legend.col.show = FALSE)

enter image description here

Martijn Tennekes
  • 1,951
  • 13
  • 19
1

Here I show how to recreate your data frame d by using dplyr. Although it is not addressing your question about how to pass numeric value to the alpha argument in tm_bubbles, consider it as a workaround.

std_agg <- d_agg %>% 
  slice(rep(row_number(), times = count)) %>%
  st_as_sf(coords = c('one', 'two'))

std_agg %>% 
  tm_shape() + 
  tm_bubbles(alpha = 0.3)

enter image description here

In fact, this base R to expand the data frame is probably more intuitive.

d_agg[rep(1:nrow(d_agg), times = d_agg$count), ]
www
  • 38,575
  • 12
  • 48
  • 84