Tôi có một câu hỏi nhỏ: Tôi không thể tìm thấy cấu trúc dữ liệu từ điển trong R, vì vậy tôi đã sử dụng danh sách thay thế (như "từ" -> số) Vì vậy, ngay bây giờ tôi có vấn đề làm thế nào để lấy danh sách khóa. Có ai biết không?
Câu trả lời:
Có, list
loại này là một ước lượng tốt. Bạn có thể sử dụng names()
trong danh sách của mình để đặt và truy xuất các 'khóa':
> foo <- vector(mode="list", length=3)
> names(foo) <- c("tic", "tac", "toe")
> foo[[1]] <- 12; foo[[2]] <- 22; foo[[3]] <- 33
> foo
$tic
[1] 12
$tac
[1] 22
$toe
[1] 33
> names(foo)
[1] "tic" "tac" "toe"
>
environment
loại được sử dụng cho điều đó trong R, nhưng nó ít phổ biến hơn / ít được biết đến hơn.
Bạn thậm chí không cần danh sách nếu tất cả các giá trị "số" của bạn đều ở cùng một chế độ. Nếu tôi lấy ví dụ của Dirk Eddelbuettel:
> foo <- c(12, 22, 33)
> names(foo) <- c("tic", "tac", "toe")
> foo
tic tac toe
12 22 33
> names(foo)
[1] "tic" "tac" "toe"
Danh sách chỉ được yêu cầu nếu giá trị của bạn ở chế độ hỗn hợp (ví dụ: ký tự và số) hoặc vectơ.
Đối với cả danh sách và vectơ, một phần tử riêng lẻ có thể được tập hợp con bằng tên:
> foo["tac"]
tac
22
Hoặc cho một danh sách:
> foo[["tac"]]
[1] 22
Để mở rộng một chút câu trả lời của Calimo, tôi trình bày thêm một số điều bạn có thể thấy hữu ích khi tạo từ điển gần như này trong R:
a) cách trả về tất cả các GIÁ TRỊ của từ điển:
>as.numeric(foo)
[1] 12 22 33
b) kiểm tra xem từ điển CHỨA TỪ KHÓA:
>'tic' %in% names(foo)
[1] TRUE
c) cách THÊM khóa, cặp giá trị MỚI vào từ điển:
c (foo, tic2 = 44)
các kết quả:
tic tac toe tic2
12 22 33 44
d) làm thế nào để đáp ứng yêu cầu của TỪ ĐIỂN THỰC - rằng các phím KHÔNG THỂ lặp lại (PHÍM DUY NHẤT)? Bạn cần kết hợp b) và c) và xây dựng hàm xác nhận xem có khóa như vậy hay không và làm những gì bạn muốn: ví dụ: không cho phép chèn, cập nhật giá trị nếu cái mới khác với cái cũ hoặc xây dựng lại khóa nào đó (ví dụ: thêm một số số vào nó để nó là duy nhất)
e) cách XÓA cặp BẰNG PHÍM khỏi từ điển:
foo <-foo [which (foo! = foo [["tac"]])]
c(foo, tic2=NULL)
. Bất kỳ công việc xung quanh?
Lý do sử dụng từ điển ngay từ đầu là hiệu suất. Mặc dù đúng là bạn có thể sử dụng các vectơ và danh sách được đặt tên cho tác vụ nhưng vấn đề là chúng đang trở nên khá chậm và bộ nhớ đói với nhiều dữ liệu hơn.
Tuy nhiên, điều mà nhiều người không biết là R thực sự có cấu trúc dữ liệu từ điển có sẵn: môi trường với tùy chọnhash = TRUE
Xem ví dụ sau để biết cách làm cho nó hoạt động:
# vectorize assign, get and exists for convenience
assign_hash <- Vectorize(assign, vectorize.args = c("x", "value"))
get_hash <- Vectorize(get, vectorize.args = "x")
exists_hash <- Vectorize(exists, vectorize.args = "x")
# keys and values
key<- c("tic", "tac", "toe")
value <- c(1, 22, 333)
# initialize hash
hash = new.env(hash = TRUE, parent = emptyenv(), size = 100L)
# assign values to keys
assign_hash(key, value, hash)
## tic tac toe
## 1 22 333
# get values for keys
get_hash(c("toe", "tic"), hash)
## toe tic
## 333 1
# alternatively:
mget(c("toe", "tic"), hash)
## $toe
## [1] 333
##
## $tic
## [1] 1
# show all keys
ls(hash)
## [1] "tac" "tic" "toe"
# show all keys with values
get_hash(ls(hash), hash)
## tac tic toe
## 22 1 333
# remove key-value pairs
rm(list = c("toe", "tic"), envir = hash)
get_hash(ls(hash), hash)
## tac
## 22
# check if keys are in hash
exists_hash(c("tac", "nothere"), hash)
## tac nothere
## TRUE FALSE
# for single keys this is also possible:
# show value for single key
hash[["tac"]]
## [1] 22
# create new key-value pair
hash[["test"]] <- 1234
get_hash(ls(hash), hash)
## tac test
## 22 1234
# update single value
hash[["test"]] <- 54321
get_hash(ls(hash), hash)
## tac test
## 22 54321
Chỉnh sửa : Trên cơ sở câu trả lời này, tôi đã viết một bài đăng trên blog với một số ngữ cảnh khác: http://blog.ephorie.de/hash-me-if-you-can
Gói băm hiện đã có sẵn: https://cran.r-project.org/web/packages/hash/hash.pdf
Ví dụ
h <- hash( keys=letters, values=1:26 )
h <- hash( letters, 1:26 )
h$a
# [1] 1
h$foo <- "bar"
h[ "foo" ]
# <hash> containing 1 key-value pair(s).
# foo : bar
h[[ "foo" ]]
# [1] "bar"
Biến thể ngắn hơn của câu trả lời Dirk:
# Create a Color Palette Dictionary
> color <- c('navy.blue', 'gold', 'dark.gray')
> hex <- c('#336A91', '#F3C117', '#7F7F7F')
> # Create List
> color_palette <- as.list(hex)
> # Name List Items
> names(color_palette) <- color
>
> color_palette
$navy.blue
[1] "#336A91"
$gold
[1] "#F3C117"
$dark.gray
[1] "#7F7F7F"
Tôi sẽ chỉ nhận xét rằng bạn có thể nhận được rất nhiều điều table
khi cố gắng "giả mạo" một từ điển, ví dụ:
> x <- c("a","a","b","b","b","c")
> (t <- table(x))
x
a b c
2 3 1
> names(t)
[1] "a" "b" "c"
> o <- order(as.numeric(t))
> names(t[o])
[1] "c" "a" "b"
Vân vân.
as.numeric()
là cần thiết. Bảng đã là số. Bạn có thể nhận được kết quả tương tự vớinames(t[order(t)])