답변:
R 언어 정의는 다음 유형의 질문에 대답하는 데 편리합니다.
R에는 세 가지 기본 색인 연산자가 있으며 다음 예제에서 구문이 표시됩니다.
x[i] x[i, j] x[[i]] x[[i, j]] x$a x$"a"
벡터 및 행렬의 경우
[[
형식과 약간의 의미 차이가 있지만 형식은 거의 사용되지 않습니다[
(예 : 이름 또는 dimnames 특성이 삭제되고 문자 색인에 부분 일치가 사용됨). 단일 인덱스 다차원 구조를 인덱싱하는 경우x[[i]]
또는x[i]
복귀한다i
토륨 순차 소자x
.목록의 경우 일반적으로
[[
단일 요소를 선택하는 데 사용 하는 반면[
선택한 요소의 목록을 반환합니다.이
[[
형식을 사용하면 정수 또는 문자 인덱스를 사용하여 단일 요소 만 선택할[
수 있지만 벡터를 사용하여 인덱싱 할 수 있습니다. 목록의 경우 인덱스는 벡터 일 수 있으며 벡터의 각 요소는 목록, 선택한 구성 요소, 해당 구성 요소의 선택된 구성 요소 등에 차례로 적용됩니다. 결과는 여전히 단일 요소입니다.
[
당신이 동일한 출력 클래스를 얻을 목록 수단 반환 항상 x[v]
관계없이 길이를 v
. 예를 들어, lapply
목록의 하위 집합을 살펴 보고 싶을 수 있습니다 lapply(x[v], fun)
. 경우 [
길이 하나의 벡터의 목록을 드롭 것,이 때마다 오류가 반환 v
길이를 가지고 있습니다.
두 방법 사이의 중요한 차이점은 추출에 사용될 때 반환하는 객체의 클래스와 값의 범위를 허용하는지 또는 할당하는 동안 단일 값을 허용하는지 여부입니다.
다음 목록에서 데이터 추출의 경우를 고려하십시오.
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의 슬롯은 원래 이름을 유지했습니다.
재귀 색인 생성을[[
위해 여기에 추가하기 만하면됩니다. 됩니다.
이것은 @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
초보자가 수동 포그를 탐색하는 데 도움을주기 위해 [[ ... ]]
표기법을 접는 기능 으로 보는 것이 도움이 될 수 있습니다. 즉, 명명 된 벡터, 목록 또는 데이터 프레임에서 '데이터를 가져 오기'를 원할 때입니다. 이러한 개체의 데이터를 계산에 사용하려면이 작업을 수행하는 것이 좋습니다. 이 간단한 예가 설명합니다.
(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
iris[[1]]
벡터를 iris[1]
반환 하지만
또 다른 구체적인 사용 사례의 경우 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"
아래의 자세한 설명을 참조하십시오.
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 ...