목록 또는 데이터 프레임의 요소에 액세스하기위한 브래킷 []와 더블 브래킷 [[]]의 차이

StackOverflow https://stackoverflow.com/questions/1169456

문제

r 목록 또는 데이터의 요소에 액세스하기위한 두 가지 다른 방법을 제공합니다. [] 그리고 [[]] 운영자.

둘의 차이점은 무엇입니까? 어떤 상황에서 다른 상황에서 다른 상황을 사용해야합니까?

도움이 되었습니까?

해결책

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() 성명. 이것은 반환 값의 차이점을 설명합니다. [] 그리고 [[]] 데이터 추출에 사용될 때. 그만큼 [] 메소드 [[]] 메소드는 클래스가 값의 유형에 따라 결정되는 객체를 반환합니다.

그래서, 사용 [] 방법 결과는 다음과 같습니다.

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

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

이거 때문입니다 [] 메소드가 목록을 반환하고 목록이 직접 전달할 유효한 개체가 아닙니다. if() 성명. 이 경우 사용해야합니다 [[]] 'bool'에 저장된 "베어"객체를 반환하기 때문에 적절한 클래스가 있습니다.

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의 마지막 두 슬롯을 덮어 쓰고 싶다고 가정 해 봅시다. 우리가 사용하려고한다면 [[]] 연산자, 이것이 일어나는 일입니다.

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"

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

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"

Hadley Wickham에서 :

From Hadley Wickham

tidyverse / purrr를 사용하여 보여주기위한 나의 (엉뚱한) 수정 :

enter image description here

여기에 추가합니다 [[ 또한 장비가 있습니다 재귀 인덱싱.

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

언급 한 바와 같이 ?"[[", 구문과 같은 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 개의 요소의 벡터가 있고 이름이있는 두 개의 요소가 더 있습니다. 그리고 멀리. 또한 단일 인덱스 또는 요소 이름을 단일 브래킷에 입력으로 제공하도록 선택할 수도 있습니다. 예 :

> 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

초보자가 수동 안개를 탐색하는 데 도움이 되려면 [[ ... ]] a 붕괴 함수 - 즉, 이름이 지정된 벡터, 목록 또는 데이터 프레임에서 '데이터를 가져 오려는 것입니다. 계산을 위해 이러한 객체의 데이터를 사용하려면이 작업을 수행하는 것이 좋습니다. 이 간단한 예는 설명 할 것입니다.

(x <- c(x=1, y=2)); x[1]; x[[1]]
(x <- list(x=1, y=2, z=3)); x[1]; x[[1]]
(x <- data.frame(x=1, y=2, z=3)); x[1]; x[[1]]

세 번째 예에서 :

> 2 * x[1]
  x
1 2
> 2 * x[[1]]
[1] 2

용어, [[ 운영자 추출물 목록에서 요소 [ 운영자가 가져갑니다 서브 세트 목록의.

또 다른 콘크리트 사용 케이스의 경우 split() 기능. 모르는 경우 split() 키 필드를 기반으로 목록/데이터 프레임을 서브 세트로 그룹화합니다. 여러 그룹에서 작동하고 플롯 등을 원할 때 유용합니다.

> class(data)
[1] "data.frame"

> dsplit<-split(data, data$id)
> class(dsplit)
[1] "list"

> class(dsplit['ID-1'])
[1] "list"

> class(dsplit[['ID-1']])
[1] "data.frame"

게다가:

다음 링크대답 여기.

다음은 다음 사항을 다루는 작은 예입니다.

x[i, j] vs x[[i, j]]

df1   <- data.frame(a = 1:3)
df1$b <- list(4:5, 6:7, 8:9)

df1[[1,2]]
df1[1,2]

str(df1[[1,2]])
str(df1[1,2])

아래에 세밀한 설명을 참조하십시오.

MTCARS라고 불리는 R의 내장 데이터 프레임을 사용했습니다.

> mtcars 
               mpg cyl disp  hp drat   wt ... 
Mazda RX4     21.0   6  160 110 3.90 2.62 ... 
Mazda RX4 Wag 21.0   6  160 110 3.90 2.88 ... 
Datsun 710    22.8   4  108  93 3.85 2.32 ... 
           ............

테이블의 맨 위 줄을 열 이름을 포함하는 헤더라고합니다. 이후 각 수평선은 데이터 행을 나타내며, 이는 행 이름으로 시작한 다음 실제 데이터가 이어집니다. 행의 각 데이터 구성원을 셀이라고합니다.

단일 사각형 브래킷 []연산자

셀에서 데이터를 검색하려면 단일 사각형 브래킷 []연산자에 행과 열 좌표를 입력합니다. 두 좌표는 쉼표로 분리됩니다. 다시 말해, 좌표는 행 위치로 시작한 다음 쉼표로 시작하여 열 위치로 끝납니다. 주문이 중요합니다.

EG 1 :- 여기 MTCARS의 두 번째 열인 첫 번째 행의 셀 값이 있습니다.

> mtcars[1, 2] 
[1] 6

EG 2 :- 또한 숫자 좌표 대신 행 및 열 이름을 사용할 수 있습니다.

> mtcars["Mazda RX4", "cyl"] 
[1] 6 

더블 스퀘어 브래킷 [[]]연산자

이중 사각형 브래킷 [[]]연산자가있는 데이터 프레임 열을 참조합니다.

EG 1 :- 내장 데이터 세트 MTCAR의 아홉 번째 열 벡터를 검색하려면 MTCAR을 작성합니다 [[9].

mtcars [[9]] [1] 1 1 1 0 0 0 0 0 0 ...

EG 2 :- 이름으로 동일한 열 벡터를 검색 할 수 있습니다.

mtcars [[ "am"]] [1] 1 1 1 0 0 0 0 0 0 ...

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top