수색…


비고

*apply 패밀리의 함수는 for 루프의 추상화입니다. for 루프와 비교할 때 *apply 함수에는 다음과 같은 장점이 있습니다.

  1. 적은 코드로 작성하십시오.
  2. 반복 카운터가 없습니다.
  3. 중간 결과를 저장하기 위해 임시 변수를 사용하지 않습니다.

그러나 for 루프는보다 일반적이며, *apply 함수를 사용하는 것이 쉽지 않은 복잡한 계산을 수행 할 수 있도록 더 많은 제어를 제공 할 수 있습니다.

관계 for 루프 및 *apply 기능이 설명된다 용 문서 for 루프 .

*apply 회원은 가족을 *apply

*apply 함수 계열 *apply 에는 주로 반환되는 출력의 종류에 따라 다른 동일한 원리의 여러 변형이 포함되어 있습니다.

기능 입력 산출
apply matrix , data.frame 또는 array 벡터 또는 행렬 (반환 된 각 요소의 길이에 따라 다름)
sapply 벡터 또는 list 벡터 또는 행렬 (반환 된 각 요소의 길이에 따라 다름)
lapply 벡터 또는 list list
vapply 벡터 또는`리스트 반환 된 각 요소의 길이에 따라 사용자 지정 클래스의 벡터 또는 행렬
mapply 여러 벡터, lists 또는 조합 list

이러한 함수가 어떻게 사용되는지 보려면 "예제"를 참조하십시오.

적용시 익명 함수 사용

apply 는 배열이나 행렬의 여백 위로 함수 (아마 익명의 것)를 평가하는 데 사용됩니다.

이 아이디어를 설명하기 위해 iris 데이터 세트를 사용합시다. iris 데이터 세트는 3 종의 150 가지 꽃을 측정합니다. 이 데이터 세트가 어떻게 구성되어 있는지 살펴 보겠습니다.

> head(iris)

  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1         5.1          3.5          1.4         0.2  setosa
2         4.9          3.0          1.4         0.2  setosa
3         4.7          3.2          1.3         0.2  setosa
4         4.6          3.1          1.5         0.2  setosa
5         5.0          3.6          1.4         0.2  setosa
6         5.4          3.9          1.7         0.4  setosa

이제 변수의 평균을 알고 싶다고 상상해보십시오. 이 문제를 해결하는 한 가지 방법은 for 루프를 사용하는 것이지만, R 프로그래머는 종종 apply 를 사용하는 것을 선호합니다 (이유는 이유를 참조하십시오).

> apply(iris[1:4], 2, mean)

Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
    5.843333     3.057333     3.758000     1.199333
  • 첫 번째 매개 변수에서 mean 은 숫자 데이터에서만 작동하므로 첫 번째 4 개 열만 포함하도록 iris 를 하위 집합으로 지정합니다.
  • 두 번째 매개 변수 값 2 는 열만 (rxC 배열의 두 번째 첨자)으로 작업하기를 원한다는 것을 나타냅니다. 1 은 행의 의미를 나타냅니다.

같은 방법으로 더 의미있는 값을 계산할 수 있습니다.

# standard deviation
apply(iris[1:4], 2, sd)
# variance
apply(iris[1:4], 2, var)

주의 사항 : R에는 열 및 행 합계를 계산하는 데 colMeans 몇 가지 기본 제공 함수가 있으며 colMeansrowMeans 의미합니다.

이제보다 의미있는 다른 작업을 해봅시다. 0.5 보다 큰 값에 대해서만 평균을 계산해 보겠습니다. 이를 위해 우리는 우리 자신의 mean 기능을 만들 것입니다.

> our.mean.function <- function(x) { mean(x[x > 0.5]) }
> apply(iris[1:4], 2, our.mean.function)

Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
    5.843333     3.057333     3.758000     1.665347

( Petal.Width 의 평균 차이점에 유의하십시오.)

그러나 나머지 코드에서이 함수를 사용하지 않으려면 어떻게해야합니까? 그런 다음 익명의 함수를 사용하여 다음과 같이 코드를 작성할 수 있습니다.

apply(iris[1:4], 2, function(x) { mean(x[x > 0.5]) })

이제까지 보았 듯이, apply 를 사용하여 하나의 행만 사용하여 데이터 세트의 열이나 행에 대해 동일한 연산을 실행합니다.

주의 사항 : apply 는 지정된 함수의 결과의 길이에 따라 매우 다른 종류의 결과를 반환하기 때문에 대화식으로 작업하지 않는 경우에는 최선의 선택이 아닐 수도 있습니다. 다른 *apply 가족 기능 중 일부는 더 예측 가능합니다 (비고 참조).

대량 파일로드

유사한 프로세스와 잘 구조화 된 파일 이름으로 작동되어야 할 수도있는 많은 수의 파일에 대해.

먼저 액세스 할 파일 이름의 벡터를 만들어야합니다. 여러 가지 옵션이 있습니다.

  • paste0() 하여 수동으로 벡터 만들기

     files <- paste0("file_", 1:100, ".rds")
    
  • list.files() 를 파일 유형에 대한 정규식 검색 용어와 함께 사용하면 동일한 유형의 다른 파일이 디렉토리에 있으면 정규 표현식 ( 정규식 )에 대한 지식이 필요합니다.

     files <- list.files("./", pattern = "\\.rds$", full.names = TRUE)
    

여기서 X 는 사용 된 파일 이름 지정 형식의 일부인 벡터입니다.

lapply 는 각 응답을 목록의 요소로 출력합니다.

readRDS.rds 파일에만 해당되며 프로세스의 적용에 따라 변경됩니다.

my_file_list <- lapply(files, readRDS)

테스트에서 for 루프보다 반드시 빠를 필요는 없지만 모든 파일을 명시 적으로 지정하지 않고 목록의 요소로 사용할 수 있습니다.

마지막으로 한 번에 여러 패키지를로드해야하는 경우가 있습니다. 이 트릭은 우리가 가져 오기를 원하는 모든 라이브러리에 library() 를 적용함으로써 아주 쉽게 할 수 있습니다 :

lapply(c("jsonlite","stringr","igraph"),library,character.only=TRUE)

여러 개의`data.frames` (`lapply`,`mapply`)

이 연습에서는 4 개의 부트 스트랩 선형 회귀 모델을 생성하고 이러한 모델의 요약을 단일 데이터 프레임에 결합합니다.

library(broom)

#* Create the bootstrap data sets
BootData <- lapply(1:4,
                   function(i) mtcars[sample(1:nrow(mtcars),
                                             size = nrow(mtcars),
                                             replace = TRUE), ])

#* Fit the models
Models <- lapply(BootData,
                 function(BD) lm(mpg ~ qsec + wt + factor(am),
                                 data = BD))

#* Tidy the output into a data.frame
Tidied <- lapply(Models,
                 tidy)

#* Give each element in the Tidied list a name
Tidied <- setNames(Tidied, paste0("Boot", seq_along(Tidied)))

이 시점에서 우리는 이름을 data.frame에 삽입하는 두 가지 접근법을 취할 수 있습니다.

#* Insert the element name into the summary with `lapply`
#* Requires passing the names attribute to `lapply` and referencing `Tidied` within
#* the applied function.
Described_lapply <- 
 lapply(names(Tidied),
        function(nm) cbind(nm, Tidied[[nm]]))

Combined_lapply <- do.call("rbind", Described_lapply)

#* Insert the element name into the summary with `mapply`
#* Allows us to pass the names and the elements as separate arguments.
Described_mapply <- 
 mapply(
  function(nm, dframe) cbind(nm, dframe),
  names(Tidied),
  Tidied,
  SIMPLIFY = FALSE)

Combined_mapply <- do.call("rbind", Described_mapply)

magrittr 스타일 파이프 팬이라면, 전체 작업을 단일 체인으로 수행 할 수 있습니다 (모델 객체 자체와 같은 중간 객체가 필요한 경우에는 그렇게하지 않는 것이 좋습니다).

library(magrittr)
library(broom)
Combined <- lapply(1:4,
                   function(i) mtcars[sample(1:nrow(mtcars),
                                             size = nrow(mtcars),
                                             replace = TRUE), ]) %>%
 lapply(function(BD) lm( mpg ~ qsec + wt + factor(am), data = BD)) %>%
 lapply(tidy) %>%
 setNames(paste0("Boot", seq_along(.))) %>%
 mapply(function(nm, dframe) cbind(nm, dframe),
        nm = names(.),
        dframe = .,
        SIMPLIFY = FALSE) %>%
 do.call("rbind", .)

내장 함수를 사용하기

내장 함수 : lapply (), sapply () 및 mapply ()

R에는 내장 함수가 있으며, 그 중 가장 잘 알려진 함수가 적용됩니다. 다음은 가장 일반적인 적용 기능 중 일부에 대한 설명입니다.

  • lapply() =는 목록을 인수로 취하여 지정된 함수를 목록에 적용합니다.
  • sapply() = lapply() 같지만 출력을 벡터 나 행렬로 단순화하려고합니다.
    • vapply() = 출력 객체의 유형을 지정 sapply() 의 변형입니다.
  • mapply() = mapply()lapply() 하지만 지정된 함수에 입력으로 여러 벡터를 전달할 수 있습니다. sapply() 처럼 단순화 될 수 있습니다.
    • Map()mapply() SIMPLIFY = FALSE mapply() 의 별명입니다.

lapply ()

lapply() 는 두 가지 다른 반복과 함께 사용할 수 있습니다.

  • lapply(variable, FUN)
  • lapply(seq_along(variable), FUN)
# Two ways of finding the mean of x
set.seed(1)
df <- data.frame(x = rnorm(25), y = rnorm(25))
lapply(df, mean)
lapply(seq_along(df), function(x) mean(df[[x]))

sapply ()

sapply() 는 출력을 벡터 또는 행렬로 변환하려고 시도합니다.

# Two examples to show the different outputs of sapply()
sapply(letters, print)  ## produces a vector
x <- list(a = 1:10, beta = exp(-3:3), logic = c(TRUE,FALSE,FALSE,TRUE))
sapply(x, quantile)  ## produces a matrix

mapply ()

mapply() 는 다중 벡터를 입력으로 취할 수 있다는 점을 제외하면 lapply() 와 매우 유사합니다 (따라서 다중 변수의 경우 m).

mapply(sum, 1:5, 10:6, 3) # 3 will be "recycled" by mapply

사용자 정의 함수식 사용

사용자 정의 함수식

사용자는 다양한 복잡성에 따라 자체 기능을 만들 수 있습니다. 다음은 Hadley Wickham의 Functionals 에서 나온 예제입니다.

randomise <- function(f) f(runif(1e3))
        
lapply2 <- function(x, f, ...) {
    out <- vector("list", length(x))
    for (i in seq_along(x)) {
        out[[i]] <- f(x[[i]], ...)
    }
    out
}

첫 번째 경우, randomise 는 단일 인수 f 받아 들여 Uniform 임의 변수의 샘플에서 호출합니다. 동등성을 증명하기 위해 아래 set.seed 를 호출합니다.

set.seed(123)
randomise(mean)
#[1] 0.4972778
    
set.seed(123)
mean(runif(1e3))
#[1] 0.4972778


set.seed(123)
randomise(max)
#[1] 0.9994045

set.seed(123)
max(runif(1e3))
#[1] 0.9994045

두 번째 예제는 functionals를 사용하여리스트 ( x )의 각 요소에 연산 ( f )을 적용하는 base::lapply 의 재 구현입니다. ... 매개 변수를 사용하면 mean 함수의 na.rm 옵션과 같이 f 추가 인수를 전달할 수 있습니다.

lapply(list(c(1, 3, 5), c(2, NA, 6)), mean)
# [[1]]
# [1] 3
# 
# [[2]]
# [1] NA

lapply2(list(c(1, 3, 5), c(2, NA, 6)), mean)
# [[1]]
# [1] 3
# 
# [[2]]
# [1] NA


lapply(list(c(1, 3, 5), c(2, NA, 6)), mean, na.rm = TRUE)
# [[1]]
# [1] 3
# 
# [[2]]
# [1] 4

lapply2(list(c(1, 3, 5), c(2, NA, 6)), mean, na.rm = TRUE)
# [[1]]
# [1] 3
# 
# [[2]]
# [1] 4


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow