R cheat sheet

Replace NA in data.frame with 0

df[is.na(df)] = 0

Sum values in data.frame by some ID

df = data.frame(id = c(‘a’, ‘a’, ‘b’, ‘b’), value = c(1,2,3,4))

aggregate(formula = value ~ id, data = df , FUN = sum)

  id value
1  a     3
2  b     7

Ignore NA

length(na.omit(x))

Only retain rows that match a values in some column

df = data.frame(id = c(‘a’, ‘a’, ‘b’, ‘b’), value = c(1,2,3,4))

selected_ids = c(‘a’)

df[df$id %in% selected_ids,]

Installing downloaded (non-Play Store) Android apk safely

1. Install App Extractor on your phone and extract the apk for the latest version of the app that you installed from Play Store. This apk is trustworthy because we know it came from the original developer. We will use this apk to obtain the signature of the developer. Let’s call this latest.apk. Move this file to a Linux computer.

2. Download the version of the app you want from apkmirror.com or any other alternative apk store. apkmirror.com is a safe source of apks. Let’s call it older.apk

3. Now we will verify that the apk from apkmirror.com is signed by the person who signed latest.apk and older.apk. apkmirror.com does it already, but we’re not trusting anyone here. In a Linux computer, run:

unzip -l latest.apk

You will see something like this at the bottom:

     2540  1980-00-00 00:00   res/xml/accessoryservices.xml
      452  1980-00-00 00:00   res/xml/licenses.xml
  4024644  1980-00-00 00:00   resources.arsc
   343789  1980-00-00 00:00   META-INF/SIGNER.SF
     4904  1980-00-00 00:00   META-INF/SIGNER.RSA <== you want this tag
   343724  1980-00-00 00:00   META-INF/MANIFEST.MF
---------                     -------
 79685136                     2927 files

Different apks have different META-INF/xxxx.RSA tags, that’s why you need to run unzip -p and see what’s in the apk you’re checking.

Then run:

unzip -p latest.apk META-INF/SIGNER.RSA | keytool -printcert | grep SHA1

You will see something like this:

         SHA1: 5F:80:65:78:25:A4:80:F6:FA:34:AB:7A:D8:EB:F8:0F:61:3D:3E:FE
         SHA1: 6D:25:66:40:C0:EF:F2:6C:CB:3A:8B:81:7C:DC:90:1F:3D:1D:77:B4
         SHA1: 17:72:90:DE:21:54:B1:F8:BA:58:36:A7:28:F3:82:09:AB:9F:7E:D5

Do the same for older.apk and see if the keys are the same. If they are, it means both apks were signed by the same person and therefore, older.apk is safe to install.

Now move older.apk to your phone, allow your phone to install apps from “Unknown sources”, click on the app in File manager and that’s it. Disable install from Unknown sources.

Limiting a user to sshfs or sftp to one directory only

Goal: allow a user to access only one directory by sftp or sshfs, and only that directory, with no shell access.

1. Create a new user and change ownership of their home directory to root (as root):

adduser testuser
chown root.root /home/testuser

2. Create a sub-directory in the user’s home:

mkdir /home/testuser/data
chown testuser.testuser /home/testuser/data

This is necessary because chroot requires the directory to be owned by root. So when the user logs in, the system changes the root to /home/testuser, which isn’t writable by testuser. Upon login, the user has to change into a directory he/she owns.

3. Add the following to your /etc/ssh/sshd_config and restart/reload ssh:

Subsystem sftp internal-sftp
Match user testuser
    ChrootDirectory /home/testuser/
    X11Forwarding no
    AllowTcpForwarding no
    ForceCommand internal-sftp

4. Now access /home/testuser/data remotely:

Via sftp:

sftp testuser@yourserver
cd data

Via sshfs:

sshfs testuser@yourserver:data ~/data

When testuser tries to mount anything outside /home/testuser/, it will get an error because there’s nothing else in the chroot environment where the user is jailed:

sshfs testuser@yourserver:/etc ~/data
testuser@yourserver:/etc/: No such file or directory

When testuser tries to login, he or she also gets an error:

ssh testuser@yourserver
This service allows sftp connections only.
Connection to yourserver closed.

Problem connecting to Eduroam Wi-Fi in Ubuntu Linux (solved)

After I downloaded SecureW2_JoinNow.run and ran it on my Ubuntu computers I was still unable to connect to Wi-Fi.

The solution is counter-intuitive. Edit the Wi-Fi configuration (Edit Connections in Network Manager) and under the tab Wi-Fi security, click on “No CA certificate is required”.

My understanding was that the whole point of running SecureW2_JoinNow.run was to obtain the CA certificate and use it. Indeed, before clicking on “No CA certificate is required”, there is a CA certificate listed.

Updating lensfun for Darktable (Linux)

I wanted to update my lens correction database in Darktable and none of the instructions I found online worked.

I found out that for Canon, the only file that Darktables reads is /usr/share/lensfun/slr-canon.xml

So I concatenated the new database (mil-canon.xml) with slr-canon.xml and overwrote /usr/share/lensfun/slr-canon.xml.

cat slr-canon.xml.old /tmp/mil-canon.xml > /tmp/x.xml

sudo cp /tmp/x.xml /usr/share/lensfun/slr-canon.xml

Then I manually removed the XML tags between the 2 .xml <lensdatabase>

</lensdatabase>
<!DOCTYPE lensdatabase SYSTEM “lensfun-database.dtd”>
<lensdatabase version=”2″>

I closed and opened Darktable and the new lenses were available for correction.

Darktable needs a more user-friendly way to use lensfun, not everybody is comfortable concatenating and editing files in the command line.