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"
답변
재귀 색인 생성을[[
위해 여기에 추가하기 만하면됩니다. 됩니다.
이것은 @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