lapply와 do.call의 차이점은 무엇입니까?


143

나는 최근에 R을 배우고 있으며 두 가지 기능에 혼동합니다 : lapplydo.call. 그것들은 mapLisp의 기능 과 비슷합니다 . 그러나 왜 다른 이름을 가진 두 가지 기능이 있습니까? 왜 R은 그냥 함수를 사용하지 map않습니까?

답변:


125

Map다른 언어의 map과 비슷한 함수 가 있습니다.

  • lapply X와 동일한 길이의 목록을 리턴합니다. 각 요소는 FUN을 X의 해당 요소에 적용한 결과입니다.

  • do.call 이름이나 함수 및 전달할 인수 목록에서 함수 호출을 구성하고 실행합니다.

  • Map주어진 벡터의 해당 요소에 함수를 적용합니다 ... Common Lisp의 mapcar와 비슷하지만 결과를 단순화하려고 시도하지 않는 Map간단한 래퍼입니다 mapply(그러나 인수는 재활용됩니다). 이후 버전에서는 결과 유형을 일부 제어 할 수 있습니다.


  1. Map 래퍼입니다 mapply
  2. lapply 특별한 경우입니다 mapply
  3. 따라서 Map그리고 lapply많은 경우에 유사합니다.

예를 들면 다음과 같습니다 lapply.

lapply(iris, class)
$Sepal.Length
[1] "numeric"

$Sepal.Width
[1] "numeric"

$Petal.Length
[1] "numeric"

$Petal.Width
[1] "numeric"

$Species
[1] "factor"

그리고 같은 사용 Map:

Map(class, iris)
$Sepal.Length
[1] "numeric"

$Sepal.Width
[1] "numeric"

$Petal.Length
[1] "numeric"

$Petal.Width
[1] "numeric"

$Species
[1] "factor"

do.call함수를 입력으로 취하고 다른 인수를 함수에 뿌립니다. 예를 들어, 목록을 더 간단한 구조 (종종 rbind또는로 cbind) 로 어셈블하는 데 널리 사용됩니다 .

예를 들면 다음과 같습니다.

x <- lapply(iris, class)
do.call(c, x)
Sepal.Length  Sepal.Width Petal.Length  Petal.Width      Species 
   "numeric"    "numeric"    "numeric"    "numeric"     "factor" 

4
실제로 내가 찾은 do.call거의 동일 apply리스프에서
Hanfei 일

마지막 do.call(cbind, x)버전이 현재 버전으로 되어 있지 Error in do.call(c, x) : 'what' must be a function or character string
않습니까

1
@snoram이 예제는 여전히 작동합니다. 함수 cbind()는 함수 와 다르며 c(), 작동하지만 결과가 다릅니다.
Andrie

61

lapply리스트에 함수를 적용하고, do.call인수리스트와 함께 함수를 호출합니다. 그것은 나에게 상당히 다른 것처럼 보입니다 ...

목록이있는 예제를 제공하려면 다음을 수행하십시오.

X <- list(1:3,4:6,7:9)

lapply를 사용하면 다음과 같이 목록의 모든 요소의 평균을 얻습니다.

> lapply(X,mean)
[[1]]
[1] 2

[[2]]
[1] 5

[[3]]
[1] 8

do.call "trim"인수가 1 일 것으로 예상되므로 오류가 발생합니다.

반면 rbind에 모든 인수를 행 방향으로 바인딩합니다. X를 행 단위로 바인딩하려면 다음을 수행하십시오.

> do.call(rbind,X)
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9

을 사용 lapply하면 R은 rbind목록의 모든 요소에 적용 되어 다음과 같이 말도 안됩니다.

> lapply(X,rbind)
[[1]]
     [,1] [,2] [,3]
[1,]    1    2    3

[[2]]
     [,1] [,2] [,3]
[1,]    4    5    6

[[3]]
     [,1] [,2] [,3]
[1,]    7    8    9

Map과 같은 것을 가지려면 ?mapply, 이것이 필요합니다 . 예를 들어 X의 모든 요소의 평균을 얻으려면 다른 트리밍으로 다음을 사용할 수 있습니다.

> mapply(mean,X,trim=c(0,0.5,0.1))
[1] 2 5 8

34

lapply유사하다 map, do.call아니다. lapply리스트의 모든 요소에 함수를 적용하고 do.call모든 함수 인수가 리스트에 있는 함수를 호출합니다. 따라서 n요소 목록의 경우 함수 호출 lapply이 있고 n함수 호출 do.call이 하나뿐입니다. 그래서 do.call매우 다르다 lapply. 이것이 귀하의 문제를 분명히하기를 바랍니다.

코드 예 :

do.call(sum, list(c(1, 2, 4, 1, 2), na.rm = TRUE))

과:

lapply(c(1, 2, 4, 1, 2), function(x) x + 1)

25

가장 간단한 말로 :

  1. lapply () 는 목록의 각 요소에 대해 지정된 함수를 적용하므로 여러 함수 호출이 있습니다.

  2. do.call () 은 주어진 함수를 목록에 전체적으로 적용하므로 함수 호출은 하나뿐입니다.

배우는 가장 좋은 방법은 R 문서의 함수 예제를 사용하는 것입니다.


12

lapply()지도와 같은 기능입니다. do.call()은 다르다. 인수를 열거하지 않고 목록 형식으로 함수에 인수를 전달하는 데 사용됩니다. 예를 들어

> do.call("+",list(4,5))
[1] 9

10

많은 답변이 있었지만 여기에 참고할만한 예가 있습니다. 다음과 같이 데이터 목록이 있다고 가정하십시오.

L=list(c(1,2,3), c(4,5,6))

lapply 함수는리스트를 리턴합니다.

lapply(L, sum) 

위의 의미는 다음과 같습니다.

list( sum( L[[1]]) , sum( L[[2]]))

이제 똑같은 일을 해 봅시다.

do.call(sum, L) 

그 뜻은

sum( L[[1]], L[[2]])

이 예에서는 21을 반환합니다. 간단히 말해서 lapply는 항상 목록을 반환하는 반면 do.call의 반환 유형은 실제로 실행되는 함수에 따라 다릅니다.


5

둘의 차이점은 다음과 같습니다.

lapply(1:n,function,parameters)

=>이 함수는 1, 매개 변수를 보냅니다 =>이 함수는 2, 매개 변수를 보냅니다

do.call 

1… n을 벡터로 보내면 매개 변수가 기능합니다

따라서 적용시 n 개의 함수 호출이 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.