Skip to content

Instantly share code, notes, and snippets.

View klmr's full-sized avatar
📦
Making your R code easier to reuse

Konrad Rudolph klmr

📦
Making your R code easier to reuse
View GitHub Profile
@klmr
klmr / Makefile
Last active March 21, 2024 19:55
Self-documenting makefiles
# Example makefile with some dummy rules
.PHONY: all
## Make ALL the things; this includes: building the target, testing it, and
## deploying to server.
all: test deploy
.PHONY: build
# No documentation; target will be omitted from help display
build:
@klmr
klmr / make_array.hpp
Last active March 18, 2024 07:14
C++11 make_array function template
template <typename... T>
constexpr auto make_array(T&&... values) ->
std::array<
typename std::decay<
typename std::common_type<T...>::type>::type,
sizeof...(T)> {
return {std::forward<T>(values)...};
}
@klmr
klmr / example.r
Last active January 24, 2024 08:27
R6 classes without the repetition
r6_class(
MyClass,
{
initialize = function (x) {
private$x = x
}
get = function () private$x
},
private = {
@klmr
klmr / config
Created October 20, 2023 09:45
Alternative R linters
linters:
config_dir = dirname(parent.frame(3L)$config_file)
lapply(dir(config_dir, '\\.r$', full.names = TRUE), source, local = environment())
lintr::linters_with_defaults(
assignment_linter = NULL,
function_left_parentheses_linter = NULL,
line_length_linter(120L),
object_usage_linter = NULL, # unusably buggy
lintr::quotes_linter("'")
)
@klmr
klmr / Calculator.cs
Created March 6, 2019 14:49
Workaround for missing numeric type constraints in C# — https://stackoverflow.com/q/32664/1968
using System;
using System.Collections.Generic;
namespace OperatorTest {
public interface ICalculator { }
public interface ICalculator<T> : ICalculator {
T Add(T a, T b);
T Divide(T a, T b);
T Multiply(T a, T b);
@klmr
klmr / lambda.r
Last active April 13, 2023 11:27
Finally a proper lambda for R
`<-` = function (body, params) {
vars = all.vars(substitute(params))
formals = as.pairlist(setNames(replicate(length(vars), quote(expr = )), vars))
eval.parent(call('function', formals, substitute(body)))
}
sapply(1 : 4, x -> 2 * x)
# 2 4 6 8
mapply(x ~ y -> x + y,
@klmr
klmr / fib.py
Last active September 14, 2022 08:39
Efficient, tail recursive fibonacci implementation for R and Python (but since they doesn’t do TCO it’s still using O(n) space)
def fib(n: int) -> int:
def f(n, a, b):
if n == 0: return a
if n == 1: return b
return f(n - 1, b, a + b)
return f(n, 0, 1)
@klmr
klmr / generator.md
Last active August 28, 2022 02:26
Python-like generators in R

A little experiment using restarts.

(And while we’re at it, let’s torture R’s syntax a little.)

![screenshot][]

In the following we will be using R’s “restarts” feature to implement the state machine that drives generators in languages such as Python. Generators allow lazily generating values on demand: a consumer invokes a generator, and consumes values as they are produced. A new value is only produced once the previous one has been consumed.

@klmr
klmr / doc-api.r
Last active June 15, 2022 12:59
Version of “Nested function structure” from https://coolbutuseless.github.io/2022/06/15/nesting-functions/ without NSE
doc = function (...) {
doc = new.env(parent = emptyenv())
doc$words = lapply(list(...), add_node, doc = doc)
doc
}
par = function (...) {
structure(list(...), class = c("par", "docnode"))
}
@klmr
klmr / check-md5.sh
Created October 12, 2012 11:10
Test checksum of gzipped FastQ files after download
#!/bin/bash
set -e
set -u
failed=0
for file in *.fq.gz; do
md5=$(gunzip -c "$file" | openssl md5 | cut -f2 -d " ")
gold=$(grep "${file/.gz/}" md5sums.txt | cut -f2)
if [ "$md5" != "$gold" ]; then