[r] 목록 또는 데이터 프레임의 요소에 액세스하기위한 대괄호 []와 이중 대괄호 [[]]의 차이점

R 목록 또는 data.frame의 요소를 액세스하는 두 다른 방법을 제공 []하고 [[]].

어떤 상황에서 다른 상황을 사용해야하는지 두 사람의 차이점은 무엇입니까?



답변

R 언어 정의는 다음 유형의 질문에 대답하는 데 편리합니다.

R에는 세 가지 기본 색인 연산자가 있으며 다음 예제에서 구문이 표시됩니다.

    x[i]
    x[i, j]
    x[[i]]
    x[[i, j]]
    x$a
    x$"a"

벡터 및 행렬의 경우 [[형식과 약간의 의미 차이가 있지만 형식은 거의 사용되지 않습니다 [(예 : 이름 또는 dimnames 특성이 삭제되고 문자 색인에 부분 일치가 사용됨). 단일 인덱스 다차원 구조를 인덱싱하는 경우 x[[i]]또는 x[i]복귀한다 i토륨 순차 소자 x.

목록의 경우 일반적으로 [[단일 요소를 선택하는 데 사용 하는 반면 [선택한 요소의 목록을 반환합니다.

[[형식을 사용하면 정수 또는 문자 인덱스를 사용하여 단일 요소 만 선택할 [수 있지만 벡터를 사용하여 인덱싱 할 수 있습니다. 목록의 경우 인덱스는 벡터 일 수 있으며 벡터의 각 요소는 목록, 선택한 구성 요소, 해당 구성 요소의 선택된 구성 요소 등에 차례로 적용됩니다. 결과는 여전히 단일 요소입니다.


답변

두 방법 사이의 중요한 차이점은 추출에 사용될 때 반환하는 객체의 클래스와 값의 범위를 허용하는지 또는 할당하는 동안 단일 값을 허용하는지 여부입니다.

다음 목록에서 데이터 추출의 경우를 고려하십시오.

foo <- list( str='R', vec=c(1,2,3), bool=TRUE )

foo에서 bool에 의해 저장된 값을 추출하여 if()명령문 내에서 사용한다고 가정하십시오 . 이것은 데이터 추출에 사용될 때 의 반환 값 []과 그 [[]]때 의 차이점을 보여줍니다 . 이 []메소드는 클래스 목록의 오브젝트 (또는 foo가 data.frame 인 경우 data.frame)를 [[]]리턴 하는 반면 클래스의 값 유형에 따라 클래스가 결정된 오브젝트를 리턴합니다.

따라서이 []방법을 사용 하면 다음과 같은 결과가 발생합니다.

if( foo[ 'bool' ] ){ print("Hi!") }
Error in if (foo["bool"]) { : argument is not interpretable as logical

class( foo[ 'bool' ] )
[1] "list"

[]메소드가 목록을 리턴했으며 목록이 if()명령문에 직접 전달하기에 유효한 오브젝트 가 아니기 때문 입니다. 이 경우 [[]]적절한 클래스를 가진 ‘bool’에 저장된 “bare”객체를 반환 하기 때문에 사용해야 합니다.

if( foo[[ 'bool' ]] ){ print("Hi!") }
[1] "Hi!"

class( foo[[ 'bool' ]] )
[1] "logical"

두 번째 차이점은 []연산자를 사용하여 데이터 프레임의 목록 또는 열에있는 슬롯 범위 에 액세스 할 수 있지만 [[]]연산자는 단일 슬롯 또는 열에 액세스하는 것으로 제한 됩니다. 두 번째 목록을 사용하여 값을 할당하는 경우를 고려하십시오 bar().

bar <- list( mat=matrix(0,nrow=2,ncol=2), rand=rnorm(1) )

foo의 마지막 두 슬롯을 bar에 포함 된 데이터로 덮어 쓰려고합니다. [[]]연산자 를 사용하려고하면 다음 과 같이됩니다.

foo[[ 2:3 ]] <- bar
Error in foo[[2:3]] <- bar :
more elements supplied than there are to replace

[[]]단일 요소에 액세스하는 것으로 제한되어 있기 때문 입니다. 우리는 사용해야합니다 []:

foo[ 2:3 ] <- bar
print( foo )

$str
[1] "R"

$vec
     [,1] [,2]
[1,]    0    0
[2,]    0    0

$bool
[1] -0.6291121

할당이 성공한 동안 foo의 슬롯은 원래 이름을 유지했습니다.


답변

이중 괄호는 목록 요소에 액세스하는 반면 단일 괄호는 단일 요소가 포함 된 목록을 제공합니다.

lst <- list('one','two','three')

a <- lst[1]
class(a)
## returns "list"

a <- lst[[1]]
class(a)
## returns "character"


답변

해들리 위컴에서 :

해들리 위컴에서

tidyverse / purrr을 사용하여 보여주기 위해 내 (비웃음) 수정 :

여기에 이미지 설명을 입력하십시오


답변

[]목록을 추출하고 목록 [[]]내의 요소를 추출합니다.

alist <- list(c("a", "b", "c"), c(1,2,3,4), c(8e6, 5.2e9, -9.3e7))

str(alist[[1]])
 chr [1:3] "a" "b" "c"

str(alist[1])
List of 1
 $ : chr [1:3] "a" "b" "c"

str(alist[[1]][1])
 chr "a"


답변

재귀 색인 생성을[[ 위해 여기에 추가하기 만하면됩니다. 됩니다.

이것은 @JijoMatthew의 답변에서 암시되었지만 탐색되지 않았습니다.

에서 언급했듯이 , where ?"[["와 같은 구문은 다음과 같이 해석됩니다.x[[y]]length(y) > 1

x[[ y[1] ]][[ y[2] ]][[ y[3] ]] ... [[ y[length(y)] ]]

참고이 있음을 하지 않는 사이의 차이에 주요 테이크 아웃을해야하는 내용을 변경 [하고 [[– 즉, 전자가 사용되는 부분 집합 , 후자가 사용되는 추출 단일 목록 요소를.

예를 들어

x <- list(list(list(1), 2), list(list(list(3), 4), 5), 6)
x
# [[1]]
# [[1]][[1]]
# [[1]][[1]][[1]]
# [1] 1
#
# [[1]][[2]]
# [1] 2
#
# [[2]]
# [[2]][[1]]
# [[2]][[1]][[1]]
# [[2]][[1]][[1]][[1]]
# [1] 3
#
# [[2]][[1]][[2]]
# [1] 4
#
# [[2]][[2]]
# [1] 5
#
# [[3]]
# [1] 6

값 3을 얻으려면 다음을 수행하십시오.

x[[c(2, 1, 1, 1)]]
# [1] 3

위의 @JijoMatthew의 답변으로 돌아가서 다음을 상기하십시오 r.

r <- list(1:10, foo=1, far=2)

특히 이것은 잘못 사용할 때 발생하는 오류 [[, 즉 다음을 설명합니다 .

r[[1:3]]

오류 r[[1:3]]: 재귀 색인 작성이 레벨 2에서 실패했습니다.

이 코드는 실제로 평가하려고 시도했고 r[[1]][[2]][[3]]중첩이 r레벨 1에서 중지 되었기 때문에 순환 인덱싱을 통한 추출 시도 [[2]]는 레벨, 즉 레벨 2에서 실패했습니다 .

오류 r[[c("foo", "far")]]: 아래 첨자 범위를 벗어남

여기서 R은 찾고있었습니다 r[["foo"]][["far"]] 존재하지 않는 있었으므로 첨자 범위를 벗어났습니다.

이러한 오류가 모두 동일한 메시지를 표시하면 약간 더 도움이 될 수 있습니다.


답변

둘 다 하위 설정 방법입니다. 단일 괄호는 목록의 하위 집합을 반환하며 그 자체가 목록이됩니다. 즉, 둘 이상의 요소를 포함하거나 포함하지 않을 수 있습니다. 반면에 이중 괄호는 목록에서 단일 요소 만 반환합니다.

단일 괄호는 우리에게 목록을 제공합니다. 목록에서 여러 요소를 반환하려는 경우 단일 괄호를 사용할 수도 있습니다. 다음 목록을 고려하십시오.

>r<-list(c(1:10),foo=1,far=2);

이제 목록을 표시하려고 할 때 목록이 반환되는 방식에 유의하십시오. r을 입력하고 Enter 키를 누릅니다

>r

#the result is:-

[[1]]

 [1]  1  2  3  4  5  6  7  8  9 10

$foo

[1] 1

$far

[1] 2

이제 우리는 단일 괄호의 마술을 볼 것입니다 :-

>r[c(1,2,3)]

#the above command will return a list with all three elements of the actual list r as below

[[1]]

 [1]  1  2  3  4  5  6  7  8  9 10

$foo

[1] 1


$far

[1] 2

화면에 r의 값을 표시하려고 할 때와 정확히 일치합니다. 즉, 단일 괄호를 사용하면 목록이 반환됩니다. 인덱스 1에는 벡터가 10 개의 요소가 있고 이름이 foo 인 요소가 두 개 더 있습니다. 그리고 지금까지. 단일 괄호에 대한 입력으로 단일 색인 또는 요소 이름을 제공 할 수도 있습니다. 예 :

> r[1]

[[1]]

 [1]  1  2  3  4  5  6  7  8  9 10

이 예제에서 우리는 하나의 인덱스 “1”을 주었고 그에 따라 하나의 요소 (10 개의 숫자 배열)를 가진리스트를 얻었습니다.

> r[2]

$foo

[1] 1

위의 예제에서 우리는 하나의 인덱스 “2”를 주었고 그에 따라 하나의 요소를 가진리스트를 얻었습니다

> r["foo"];

$foo

[1] 1

이 예제에서 우리는 하나의 요소의 이름을 전달했고 그 결과로 하나의 요소와 함께 목록이 반환되었습니다.

다음과 같은 요소 이름의 벡터를 전달할 수도 있습니다.

> x<-c("foo","far")

> r[x];

$foo

[1] 1

$far
[1] 2

이 예에서는 “foo”및 “far”라는 두 요소 이름을 가진 벡터를 전달했습니다.

그 대가로 우리는 두 가지 요소가있는 목록을 얻었습니다.

짧은 단일 괄호는 항상 단일 괄호에 전달하는 요소 수 또는 색인 수와 동일한 요소 수를 가진 다른 목록을 반환합니다.

반대로 이중 괄호는 항상 하나의 요소 만 반환합니다. 이중 브래킷으로 이동하기 전에 명심해야 할 메모입니다.
NOTE:THE MAJOR DIFFERENCE BETWEEN THE TWO IS THAT SINGLE BRACKET RETURNS YOU A LIST WITH AS MANY ELEMENTS AS YOU WISH WHILE A DOUBLE BRACKET WILL NEVER RETURN A LIST. RATHER A DOUBLE BRACKET WILL RETURN ONLY A SINGLE ELEMENT FROM THE LIST.

몇 가지 예를 들어 보겠습니다. 굵게 표시된 단어를 메모하고 아래 예를 수행 한 후에 다시 입력하십시오.

이중 괄호는 인덱스의 실제 값을 반환합니다 (목록을 반환 하지는 않음 ).

  > r[[1]]

     [1]  1  2  3  4  5  6  7  8  9 10


  >r[["foo"]]

    [1] 1

이중 괄호의 경우 벡터를 전달하여 둘 이상의 요소를 보려고하면 해당 요구를 충족시키지 않고 단일 요소를 반환하기 때문에 오류가 발생합니다.

다음을 고려하세요

> r[[c(1:3)]]
Error in r[[c(1:3)]] : recursive indexing failed at level 2
> r[[c(1,2,3)]]
Error in r[[c(1, 2, 3)]] : recursive indexing failed at level 2
> r[[c("foo","far")]]
Error in r[[c("foo", "far")]] : subscript out of bounds