간단한 배경 : 널리 사용되는 많은 (대부분의) 현대 프로그래밍 언어에는 적어도 몇 개의 ADT (추상 데이터 유형)가 공통적으로 있습니다.
문자열 (문자로 구성된 시퀀스)
목록 (정렬 된 값 모음) 및
지도 기반 유형 (키를 값에 매핑하는 정렬되지 않은 배열)
R 프로그래밍 언어에서 처음 두 개는 각각 character및 로 구현됩니다 vector.
R을 배우기 시작했을 때, 거의 처음부터 두 가지가 명백 list했습니다 .R에서 가장 중요한 데이터 유형입니다 (R의 부모 클래스이기 때문에 data.frame). 그리고 두 번째로, 그들이 어떻게 작동했는지 이해할 수 없었습니다. 내 코드에서 올바르게 사용하기에 충분하지 않습니다.
우선 R의 list데이터 유형은 맵 ADT ( dictionaryPython, NSMutableDictionaryObjective C, hashPerl 및 Ruby, object literalJavascript 등)를 간단하게 구현 한 것 같습니다 .
예를 들어, 키-값 쌍을 생성자 (Python의 경우는 dict아님 list) 에 전달하여 Python 사전과 같이 생성합니다 .
x = list("ev1"=10, "ev2"=15, "rv"="Group 1")
그리고 파이썬 사전과 같이 R List의 항목에 액세스합니다 (예 :) x['ev1']. 마찬가지로 다음과 같이 '키' 또는 '값' 만 검색 할 수 있습니다 .
names(x) # fetch just the 'keys' of an R list
# [1] "ev1" "ev2" "rv"
unlist(x) # fetch just the 'values' of an R list
# ev1 ev2 rv
# "10" "15" "Group 1"
x = list("a"=6, "b"=9, "c"=3)
sum(unlist(x))
# [1] 18
그러나 R list은 다른지도 유형의 ADT 와 다릅니다 (어쨌든 내가 배운 언어 중에서). 내 생각에 이것은 S의 초기 사양, 즉 기초부터 데이터 / 통계 DSL (도메인 특정 언어)을 설계하려는 의도의 결과라고 생각합니다.
list널리 사용되는 다른 언어 (예 : Python, Perl, JavaScript)에서 R 과 매핑 유형의 세 가지 중요한 차이점 :
먼저 , listR에서 S는이다 정렬 막 벡터처럼 그 값을 키가되는 경우에도 (즉, 키는 임의의 해쉬 값이 아닌 정수 순차적 일 수있다), 수집. 거의 항상 다른 언어의 매핑 데이터 형식이 정렬되지 않았습니다 .
둘째 , listS는 당신이 전달되지 않습니다에도 불구하고 기능에서 반환 할 수 있습니다 list당신이 함수를 호출 할 때, 그리고 비록 (가) 반환 된 기능 list(명시 적)이 포함되어 있지 않습니다 list물론 (생성자, 당신에 의해 실제로이 처리 할 수 을 호출하여 반환 된 결과를 래핑 unlist:
x = strsplit(LETTERS[1:10], "") # passing in an object of type 'character'
class(x) # returns 'list', not a vector of length 2
# [1] list
세 번째 R의의 독특한 기능 list들 : 그들이 다른 ADT의 구성원이 될 수 있다는 것을하지 않는 것, 당신이 그렇게하려고하면 다음 기본 컨테이너는 강제 변환됩니다 list. 예 :
x = c(0.5, 0.8, 0.23, list(0.5, 0.2, 0.9), recursive=TRUE)
class(x)
# [1] list
여기에서의 나의 의도는 언어를 비판하거나 언어를 문서화하는 방법이 아니다. 마찬가지로 list데이터 구조 또는 작동 방식에 문제가 있음을 제안하지 않습니다 . 내가 추구하는 것은 그것들이 어떻게 작동하는지에 대한 나의 이해로 코드에서 올바르게 사용할 수 있습니다.
내가 더 잘 이해하고 싶은 종류는 다음과 같습니다.
함수 호출이 언제
list(예 :strsplit위에서 언급 한 표현)을 반환 할 것인지를 결정하는 규칙은 무엇입니까 ?명시 적으로 이름을
list(예 :)에 할당하지 않으면list(10,20,30,40)기본 이름은 1로 시작하는 순차 정수입니까? (그렇지 않으면 우리는 이러한 유형의 강요 할 수없는 것, 내가 생각,하지만 난 대답은 '예'확신에서 멀리이다listw /로 전화 벡터에unlist.)이 두 개의 다른 연산자 인
[], 및 왜 같은 결과를[[]]반환 합니까?x = list(1, 2, 3, 4)두 표현식 모두 "1"을 반환합니다.
x[1]x[[1]]왜이 두 표현식 이 같은 결과를 반환 하지 않습니까?
x = list(1, 2, 3, 4)x2 = list(1:4)
R 문서 ( ?list, R-intro) 를 가리 키지 마십시오. 필자는이 내용을주의 깊게 읽었으며 위에서 언급 한 유형의 질문에 대답하는 데 도움이되지 않습니다.
(마지막으로, 최근 에 S4 클래스를 통해 일반적인 맵 유형 동작 hash을 구현 하는 R 패키지 (CRAN에서 사용 가능)를 배우고 사용하기 시작했습니다 .이 패키지를 확실히 추천 할 수 있습니다.)
listR의 해시와는 다른 방법으로 귀하의 목록을 확장하는 사람 은 없었습니다. 주목할만한 것이 하나 더 있습니다. listR에서 동일한 참조 이름을 가진 두 개의 멤버를 가질 수 있습니다. 이것이 obj <- c(list(a=1),list(a=2))유효하고 이름이 'a'인 두 개의 값이있는 목록을 리턴한다고 가정하십시오. 이 경우에 대한 호출 obj["a"]은 첫 번째 일치하는 목록 요소 만 리턴합니다. R의 환경을 사용하여 참조 된 이름 당 하나의 항목 만있는 해시와 유사한 동작을 얻을 수 있습니다 (예x <- new.env(); x[["a"]] <- 1; x[["a"]] <- 2; x[["a"]]
x = list(1, 2, 3, 4)하면 두 가지 모두 같은 결과를 반환하지 않습니다 :x[1], 및x[[1]]. 첫 번째는 목록을 반환하고 두 번째는 숫자 벡터를 반환합니다. 아래로 스크롤하면 Dirk 이이 질문을 올바르게 처리 한 유일한 응답자 인 것 같습니다.