Неэффективность циклов не должна беспокоить, поскольку циклы не будут большими.Однако семейство функций apply
одновременно и выразительно, и удобно, поэтому стоит задуматься.Это избавляет от необходимости предварительно выделять структуры данных для результата и избегает громоздкого двойного цикла.
Я проиллюстрирую это с помощью набора игрушечных данных, делая один шаг за раз.Давайте создадим фрейм данных df
с тремя столбцами с именами «x», «y» и «z»:
> n <- 1:5; (df <- as.data.frame(cbind(x=n, y=n*10, z=n*100)))
x y z
1 1 10 100
2 2 20 200
3 3 30 300
4 4 40 400
5 5 50 500
Массив различных пар имен df
легко создается с помощью combn
, как предлагается в вопросе:
> combn(names(df), 2)
[,1] [,2] [,3]
[1,] "x" "x" "y"
[2,] "y" "z" "z"
Вы можете использовать каждый столбец для индексации по столбцам df
:
> apply(combn(names(df), 2), 2, function(i) df[i])
[[1]]
x y
1 1 10
2 2 20
3 3 30
4 4 40
5 5 50
[[2]]
x z
1 1 100
2 2 200
3 3 300
4 4 400
5 5 500
[[3]]
y z
1 10 100
2 20 200
3 30 300
4 40 400
5 50 500
Результатом является список фреймов данныхкаждый с соответствующим образом названными столбцами.Поэтому вы можете вызвать lapply
для генерации таблиц.Вот полное решение.Выдает список таблиц.
> lapply(apply(combn(names(df), 2), 2, function(i) df[i]), table)
[[1]]
y
x 10 20 30 40 50
1 1 0 0 0 0
2 0 1 0 0 0
3 0 0 1 0 0
4 0 0 0 1 0
5 0 0 0 0 1
[[2]]
z
x 100 200 300 400 500
1 1 0 0 0 0
2 0 1 0 0 0
3 0 0 1 0 0
4 0 0 0 1 0
5 0 0 0 0 1
[[3]]
z
y 100 200 300 400 500
10 1 0 0 0 0
20 0 1 0 0 0
30 0 0 1 0 0
40 0 0 0 1 0
50 0 0 0 0 1