Programming

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

procodes 2020. 2. 13. 00:58
반응형

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


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"

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

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"

해들리 위컴에서 :

해들리 위컴에서

tidyverse / purrr을 사용하여 표시하는 내 (크 래피 모양) 수정 :

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


재귀 인덱싱을[[ 위해 여기에 추가하기 만하면 됩니다.

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

에서 언급 한 ?"[["것처럼 x[[y]], where 와 같은 구문은 다음과 같이 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

초보자가 수동 포그를 탐색하는 데 도움이되도록 [[ ... ]]표기법을 접는 기능 으로 보는 것이 도움이 될 수 있습니다. 즉, 명명 된 벡터, 목록 또는 데이터 프레임에서 '데이터를 가져 오기'를 원할 때입니다. 이러한 개체의 데이터를 계산에 사용하려면이 작업을 수행하는 것이 좋습니다. 이 간단한 예가 설명합니다.

(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])

아래의 자세한 설명을 참조하십시오.

R에서 내장 데이터 프레임 인 mtcars를 사용했습니다.

> 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 ... 
           ............

테이블의 맨 위 줄을 열 이름이 포함 된 헤더라고합니다. 그 후 각 수평선은 데이터 행을 나타내며, 행은 행 이름으로 시작하여 실제 데이터가 뒤 따릅니다. 행의 각 데이터 멤버를 셀이라고합니다.

단일 대괄호 "[]"연산자

셀에서 데이터를 검색하려면 단일 대괄호 "[]"연산자로 행 및 열 좌표를 입력합니다. 두 좌표는 쉼표로 구분됩니다. 즉, 좌표는 행 위치로 시작한 다음 쉼표로 시작하고 열 위치로 끝납니다. 순서가 중요합니다.

예 1 :-mtcars의 첫 번째 행, 두 번째 열의 셀 값입니다.

> mtcars[1, 2] 
[1] 6

예를 들어, 2 : 숫자 좌표 대신 행과 열 이름을 사용할 수 있습니다.

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

이중 대괄호 "[[]]"연산자

이중 대괄호 "[[]]"연산자를 사용하여 데이터 프레임 열을 참조합니다.

예 1 : 내장 데이터 세트 mtcar의 9 번째 열 벡터를 검색하기 위해 mtcars [[9]]를 작성합니다.

mtcars [[9]] [1] 110100000 ...

예 2 :-이름으로 같은 열 벡터를 검색 할 수 있습니다.

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

참고 URL : https://stackoverflow.com/questions/1169456/the-difference-between-bracket-and-double-bracket-for-accessing-the-el



반응형