sapply() с помощью strsplit в R

Я нашел этот код:

string = c("G1:E001", "G2:E002", "G3:E003")
> sapply(strsplit(string, ":"), "[", 2)
[1] "E001" "E002" "E003"

ясно, что strsplit(string, ":") возвращает векторы размера 3, где каждый компонент i является вектором размера 2, содержащим Gi и E00i.

Но почему еще два аргумента "[", 2 приводят к выбору только тех E00i? Насколько я вижу, единственными аргументами, принимаемыми функцией, являются:

sapply(X, FUN, ..., simplify = TRUE, USE.NAMES = TRUE) 

person Leonardo    schedule 05.07.2015    source источник


Ответы (3)


Посмотрите документы для ?sapply:

 sapply(X, FUN, ..., simplify = TRUE, USE.NAMES = TRUE)

 FUN: the function to be applied to each element of ‘X’: see
      ‘Details’.  In the case of functions like ‘+’, ‘%*%’, the
      function name must be backquoted or quoted.

 ...: optional arguments to ‘FUN’.

В этом и заключается ваш ответ. В вашем случае FUN это [. «Необязательные аргументы для fun» в вашем случае равны «2», поскольку в вашем вызове они сопоставляются с .... Таким образом, в этом случае sapply вызывает [ со значениями в списке в качестве первого аргумента и 2 в качестве второго. Рассмотреть возможность:

x <- c("G1", "E001")   # this is the result of `strsplit` on the first value

Затем:

`[`(x, 2)      # equivalent to x[2]
# [1] "E001"

Это то, что sapply делает в вашем примере, за исключением того, что он применяется к каждому вектору символов длиной 2, возвращаемому strsplit.

person BrodieG    schedule 06.07.2015

Вы можете использовать sub для получения ожидаемого результата вместо использования strsplit/sapply

 sub('.*:', '', string)
 #[1] "E001" "E002" "E003"

Что касается вашего кода, strsplit вывод представляет собой список, и список может быть обработан с применением функций семейства sapply/lapply/vapply/rapply и т. д. В этом случае каждый элемент списка имеет длину 2, и мы выбираем второй элемент.

strsplit(string, ":")
#[[1]]
#[1] "G1"   "E001"

#[[2]]
#[1] "G2"   "E002"

#[[3]]
#[1] "G3"   "E003"

lapply(strsplit(string, ":"), `[`, 2)
#[[1]]
#[1] "E001"

#[[2]]
#[1] "E002"

#[[3]]
#[1] "E003"

В случае sapply по умолчанию используется вариант simplify=TRUE.

 sapply(strsplit(string, ":"), `[`, 2, simplify=FALSE)
#[[1]]
#[1] "E001"

#[[2]]
#[1] "E002"

#[[3]]
#[1] "E003"

[ можно заменить анонимным вызовом функции

sapply(strsplit(string, ":"), function(x) x[2], simplify=FALSE)
#[[1]]
#[1] "E001"

#[[2]]
#[1] "E002"

#[[3]]
#[1] "E003"
person akrun    schedule 05.07.2015
comment
Это не просто замена, это аналог. x[2] совпадает с `[`(x,2) - person thelatemail; 06.07.2015

Потому что вывод strsplit() — это список. "[" относится к элементам списка, а 2 указывает, что выбран второй элемент члена списка. Функция sapply() гарантирует, что это будет сделано для каждого члена списка. Здесь [ — это функция из sapply(), которая применяется к списку strsplit() и вызывается с дополнительным параметром 2.

> strsplit(string, ":")
#[[1]]
#[1] "G1"   "E001"
#
#[[2]]
#[1] "G2"   "E002"
#
#[[3]]
#[1] "G3"   "E003"
#
> str(strsplit(string, ":"))
#List of 3
# $ : chr [1:2] "G1" "E001"
# $ : chr [1:2] "G2" "E002"
# $ : chr [1:2] "G3" "E003"
person RHertel    schedule 05.07.2015