Здесь аналогичен подход к вложенным циклам, который использует lapply()
.
Если у вас большой набор данных, использование lapply()
может значительно улучшить скорость по сравнению с использованием циклов.Циклы медленны в R, и рекомендуется использовать векторизованные функции в семействе *apply
, где это возможно.
Я рассмотрю пример, и вы, возможно, сможете адаптировать его к своемунабор данных.
Сначала создадим примерный фрейм данных 3x3 с именем df
, со столбцами a
, b
и c
и строками d
, e
и f
:
> df <- data.frame(a = sample(3), b = sample(3), c = sample(3))
> rownames(df) <- c('d','e','f')
Давайте посмотрим на df
и его транспонирование t(df)
:
> df
a b c
d 3 1 3
e 1 3 1
f 2 2 2
> t(df)
d e f
a 3 1 2
b 1 3 2
c 3 1 2
Допустим, мы хотим intersect
векторы столбцов df
и t(df)
,Теперь мы используем вложенные операторы lapply()
для запуска intersect()
для векторов столбцов как из df
, так и из транспонирования t(df)
:
> result <- lapply(df, function(x) lapply(as.data.frame(t(df)), function(y) intersect(x,y)))
Результатом является list()
, показывающий результаты пересечения:
> is.list(result)
[1] TRUE
> print(result)
$a
$a$d
[1] 3 1
$a$e
[1] 3 1
$a$f
[1] 2
$b
$b$d
[1] 1 3
$b$e
[1] 1 3
$b$f
[1] 2
$c
$c$d
[1] 3 1
$c$e
[1] 3 1
$c$f
[1] 2
Давайте снова посмотрим на df
и t(df)
и посмотрим, как читать эти результаты:
> df
a b c
d 3 1 3
e 1 3 1
f 2 2 2
> t(df)
d e f
a 3 1 2
b 1 3 2
c 3 1 2
Давайте посмотрим на df$a
, пересекаемый с t(df)$d
,t(df)$e
и t(df)$f
:
$a
$a$d
[1] 3 1
Пересекающиеся векторы a
и d
: {3,1,2}^{3,1,3} = {3,1}
$a$e
[1] 3 1
Снова с векторами a
и e
: {3,1,2}^{1,3,1} = {3,1}
$a$f
[1] 2
И наконец, с векторами a
и f
: {3,1,2}^{2,2,2} = {2}
Далее следуют другие элементы в result
.
Чтобы расширить это на ваш набор данных, представьте, что ваши столбцы фрейма данных обозначены как localities , а столбцы транспонированных фреймов данных - как ваш вид .Затем используйте lapply()
, как показано выше.
Чтобы разбить вложенный оператор lapply()
, начните с внутреннего lapply()
:
lapply(as.data.frame(t(df)), function(y) ... )
Что это означаетчто каждый вектор столбца в t(df)
- столбцы $ d, $ e и $ f - представлены переменной y
в function(y)
.Мы вернемся к ...
через секунду.
Теперь давайте посмотрим на внешний lapply()
:
lapply(df, function(x) ... )
Что это означает, что каждый столбец-вектор в df
- столбцы $ a, $ b и $ c - представлены переменной x
в function(x)
.
Теперь давайте объясним ...
.
Внешняя ...
- это любая функция x
- это может быть length()
, sum()
и т. Д. И даже другая lapply()
.Внутренний lapply()
имеет свою собственную функцию и имя переменной y
, поэтому внутренний ...
может запускать функцию как на x
, так и на y
.
Итак, вот что мы делаем:каждый вектор столбца в df
, мы запускаем функцию на этом df
-векторе и каждый вектор столбца в транспонированной t(df)
.В нашем примере функция, которую мы будем запускать на x
и y
, равна intersect()
:
> result <- lapply(df, function(x) lapply(as.data.frame(t(df)), function(y) intersect(x,y)))