Starlog

Alright, for the next several weeks, I’ll be taking a break for R, data-analysis, visualizations and other stuff on this blog.

This will be my StarLog.

I’ve joined a course on EdX: “Star Trek: Inspiring Culture and Technology”, and this is my homework 🙂

First job is to introduce myself, and what brought me to this course.

My name is Christian Knudsen, I am 44 years old. And I did not grow up with Star Trek. Actually I was a bit dismissive of trekkies. Such geeks! I had watched a few episodes of TNG on danish television, and had a bit of a crush on Wesley. But never more than that. About 14 years ago, I embraced my inner trekkie. A complete season of DS9 was on sale. I don’t remember which, but I bought it. Watched it. And was hooked. I acquired the complete collection, and watched it all. I watched it in order. I watched it in order with my husband again. And currently we are watching it in StarDate order. We have been to cons. The priest referenced Star Trek at our wedding. There is a Star Trek quote inscribed in our rings.

To me, Star Trek is the promise of a bright future. The promise, that humanity has a chance. That we will, somehow, overcome our problems. Like all good science fiction, it tackles current issues, and provoces thought. Living in a liberal, social-democratic country in northern Europe, it is sometimes difficult to understand exactly why a controversial subject is that controversial. The progressive themes are not necessarily viewed as that progressive in a Danish context. That also gives an interesting perspective on an american culture, that can appear very alien to outsiders.

And that was the way I got here. The final ingredient was a link on a danish Star Trek group on Facebook!

And with that, I earned my promotion to CWO!

Where to see Great Pandas

Zoos with Great Pandas in their exhibitions, as pr. medio March ’19.

And Copenhagen Zoo, which will get their pandas in april.

Propagandabjørne

Lige om lidt lander der pandabjørne i København. Danmark har fået lov at låne et par pandaer af Kina. Det fordrer normalt at vi efterfølgende ikke taler for højt om menneskerettigheder og den slags, og det hjalp sikkert også at den danske regering (eller i hvert fald politiet, helt på eget initiativ, og slet ikke efter opfordring fra nogen som helst, og i hvert fald ikke fra ministre der kunne tænkes at blive holdt politisk ansvarlige) viste sig villige til at se stort på Grundloven.

Anyway. Hvis man godt vil se pandabjørne, hvor kan man så gøre det? Hvilke zoos har pandaer? Om lidt kan man gøre det i København. Men der er også andre steder:

Dette er, pr. midten af marts 2019, de zoologiske haver, der har pandaer i deres samling. Og så Københavns Zoo, på forventet efterbevilling.

Corresponding value to a max-value

One of our users need to find the max-value of a variable. He also needs to find the corresponding value in another variable.
As in – the maximum value in column A is in row 42. What is the value in column B, row 42.

And of course we need to do it for several groups.

Let us begin by making a dataset. Four groups in id,

library(tidyverse)
id <- 1:3
val <- c(10,20)
kor <- c("a", "b", "c")


example <- expand.grid(id,val) %>% 
  as_tibble() %>% 
  arrange(Var1) %>% 
  cbind(kor, stringsAsFactors=F) %>% 
  rename(group=Var1, value=Var2, corr = kor)

example
##   group value corr
## 1     1    10    a
## 2     1    20    b
## 3     2    10    c
## 4     2    20    a
## 5     3    10    b
## 6     3    20    c

We have six observations, divided into three groups. They all have a value, and a letter in “corr” that is the corresponding value we are interested in.

So. In group 1 we should find the maximum value 20, and the corresponding value “b”.
In group 2 the max value is stil 20, but the corresponding value we are looking for is “a”.
And in group 3 the max value is yet again 20, but the corresponding value is now “c”.

How to do that?

example %>%
  group_by(group) %>% 
  mutate(max=max(value)) %>% 
  mutate(max_corr=corr[(value==max)]) %>% 
  ungroup()
## # A tibble: 6 x 5
##   group value corr    max max_corr
##   <int> <dbl> <chr> <dbl> <chr>   
## 1     1   10. a       20. b       
## 2     1   20. b       20. b       
## 3     2   10. c       20. a       
## 4     2   20. a       20. a       
## 5     3   10. b       20. c       
## 6     3   20. c       20. c

The maximum value for all groups is 20. And the corresponding value to that in the groups is b, a and c respectively.

Isn’t there an easier solution using summarise function? Probably. But our user needs to do this for a lot of variables. And their names have nothing in common.

Digital Natives

One can only hope that the concept “Digital Natives” will soon be laid to rest. Or at least all the ideas about what they can do.

A digital native is a person that grows up in the digital age, in contrast to digital immigrants, that got their familiarity with digital systems as an adult.

And there are differences. Digital natives assumes that everything is online. Stuff that is not online does not exist. Their first instinct is digital.

However, in the library world, and a lot of other places, the idea has been, that digital natives, because they have never experienced a world without computers, groks them. That they just know how to use them, and how to use them in a responsible and effective way.

That is, with a technical term, bovine feces. And for far too long, libraries (and others) have ignored the real needs, assuming that there was now suddenly no need for instruction in IT-related issues. Becase digital natives.

Being a digital native does not mean that you know how to code.

Being a digital native does not mean that you know how to google efficiently.

Being a digital native does not mean that you are magically endowed with the ability to discern fake news from facts.

I my self is a car native. I have grown up in an age where cars were ubiquitous. And I still had to take the test twice before getting my license. I was not able to drive a car safely, just because I have never known a world without cars. Why do we assume that a digital native should be able to use a computer efficiently?

The next project

For many years, from 1977 to 2006, there was a regular feature in the journal for the Danish Chemical Society. “Kemiske småforsøg”, or “Small chemical experiments”. It was edited by the founder of the Danish Society for Historical Chemistry, and contained a lot of interesting chemistry, some of it with a historical angle.

The Danish Society for Historical Chemistry is considering collecting these experiments, and publishing them. It has been done before, but more experiments were published after that.

We still don’t know if we will be allowed to do it. And it is a pretty daunting task, as there are several hundred experiments. But that is what I’m spending my free time on at the moment. If we get i published, it will be for sale at the website of the Danish Society for Historical Chemistry.

Project Euler 4

A palindromic number is similar to a palindrome. It is the same read both left to right, and right to left.

Project Euler tells us, that the largest palindrom made from the product of two 2-digit numbers is 9009. That number is made by multiplying 91 and 99.

I must now find the largest palindrome, made from the product of two 3-digit numbers.

What is given, is that the three digit numbers cannot end with a zero.

There are probably other restrictions as well.

I’ll need a function that tests if a given number is palindromic.

palindromic <- function(x){
  sapply(x, function(x) (str_c(rev(unlist(str_split(as.character(x),""))), collapse="")==as.character(x)))
}

The function part converts x to character, splits it in individual characters, unlists the result, reverses that, and concatenates it to a string. Then it is compared to the original x – converted to a character.
The sapply part kinda vectorises it. But it is still the slow part.

If I could pare the number of numbers down, that would be nice.

One way would be to compare the first and last digits in the number.

first_last <- function(x) { 
  x %/% 10^(floor(log10(x))) == x%%10
}

This function finds the number of digits – 1 in x. I then modulo-divide the number by 10 to the number of digits minus 1. That gives me the first digit, that I compare with the last. If the first and the last digit is the same – it returns true.

Now I am ready. Generate a vector of all three-digit numbers from 101 to 999. Expand the grid to get all combinations. Convert to a tibble,
filter out all the three-digit numbers that end with 0. Calculate a new column as the multiplication of the two numbers, filter out all the results where the first and last digit are not identical, and then filter out the results that are not palindromic. Finally, pass it to max (using %$% to access the individual variables), and get the result.

library(dplyr)
library(magrittr)

res <- 101:999 %>% 
  expand.grid(.,.) %>% 
  as_tibble() %>% 
  filter(Var1 %% 10 != 0, Var2 %% 10 != 10) %>% 
  mutate(pal = Var1 * Var2) %>% 
  filter(first_last(pal)) %>% 
  filter(palindromic(pal)) %$% 
  max(pal)

There are probably faster ways of doing this…

Angående socialdemokraternes tilbagetrækningsreform

Et af målene med tilbagetrækningsreformen er at alle skal få ca. lige mange raske og sunde år på pension. Det er urimeligt at folk med høje uddannelser kan gå på pension samtidig med nedslidte murersvende. For de højt uddannede får flere raske år.

Må jeg i al fredsommelighed fremføre, at kvinder i Danmark pt lever 3 år længere end mænd. Og i snit i øvrigt er mere sunde og raske end mænd. Betyder det at Socialdemokraterne går ind for at mænd skal kunne gå på pension ca. tre år tidligere end kvinder?