Словари и пары

В R мне было интересно, могу ли я иметь словарь (в некотором смысле, как Python), где у меня есть пара (i, j) в качестве ключа с соответствующим целочисленным значением. Я не видел простого или интуитивно понятного способа построить это в R. Визуализация моего словаря будет:

(1, 2) --> 1

(1, 3) --> 3

(1, 4) --> 4

(1, 5) --> 3

EDIT: Строка кода для вставки этих пар ключ-значение находится в цикле со счетчиками i и j. Например, предположим, что у меня есть:

for(i in 1: 5)
{  
  for(j in 2: 4)
  {
    maps[i][j] = which.min(someVector)
  }
}

Как изменить maps[i][j], чтобы получить нужные мне функции?


person CodeKingPlusPlus    schedule 18.04.2013    source источник
comment
Можно ли предположить, что, как в вашем примере, i и j будут целыми числами? Если это так, вы можете просто использовать многомерный массив. В данном случае просто 2D (матрица).   -  person Jeff Allen    schedule 19.04.2013
comment
конструкции R для этого data.frame и data.table   -  person eddi    schedule 19.04.2013
comment
Да, и как вы могли бы сделать это, используя только карту между целыми числами и целыми числами?   -  person CodeKingPlusPlus    schedule 19.04.2013
comment
или списки: x=list('2'=3, '1'=4); x[['1']] ; x$'1'   -  person Justin    schedule 19.04.2013


Ответы (5)


Вы можете сделать это со списком векторов.

maps <- lapply(vector('list',5), function(i) integer(0))
maps[[1]][2] <- 1
maps[[1]][3] <- 3
maps[[1]][4] <- 4
maps[[1]][5] <- 3

Тем не менее, вероятно, есть лучший способ сделать то, что вы пытаетесь сделать, но вы не дали нам достаточно информации.

person Joshua Ulrich    schedule 18.04.2013

И именованные списки, и среды обеспечивают сопоставление, но между строкой символов (имя, которое действует как ключ) и произвольным объектом R (значением). Если ваши i и j простые (как они выглядят в вашем примере, будучи целыми числами), вы можете легко сделать уникальную строку из их пары, объединив их с некоторым разделителем. Это сделает допустимое имя/ключ

mykey <- function(i, j) {
  paste(i, j, sep="|")
}

maps <- list()
for(i in 1: 5) {  
  for(j in 2: 4) {
    maps[mykey(i,j)] <- which.min(someVector)
  }
}

Вы можете извлечь любое значение для конкретных i и j с помощью

maps[[mykey(i,j)]]
person Brian Diggs    schedule 18.04.2013
comment
Или вы можете просто использовать список векторов: list(c(0,1,3,4,3)). - person Joshua Ulrich; 19.04.2013
comment
@JoshuaUlrich Как же тогда искать? - person Brian Diggs; 19.04.2013
comment
Это ИМХО лучший ответ, поскольку он может обобщаться на любое количество измерений и не имеет начального предположения о количестве элементов для хранения. - person flodel; 19.04.2013

Вот как это сделать в data.table, который будет быстрым и легко расширяемым:

library(data.table)
d = data.table(i = 1, j = 2:5, value = c(1,3,4,3), key = c("i", "j"))

# access the i=1,j=3 value
d[J(1, 3)][, value]

# change that value
d[J(1, 3), value := 12]

# do some vector assignment (you should stop thinking loops, and start thinking vectors)
d[, value := i * j]

и т. д.

person eddi    schedule 18.04.2013

Вы можете просто использовать data.frame:

a = data.frame(spam = c("alpha", "gamma", "beta"), 
               shrub = c("primus","inter","parus"),
               stringsAsFactors = FALSE)
rownames(a) = c("John", "Eli","Seth")
> a
      spam  shrub
John alpha primus
Eli  gamma  inter
Seth  beta  parus

>     a["John", "spam"]
[1] "alpha"

Это обрабатывает случай с объектом стиля 2d словаря с именованными ключами. Ключи также могут быть целыми числами, хотя они могут быть символами, а не числами.

person Paul Hiemstra    schedule 18.04.2013
comment
Это интересно, посмотрите мою правку. Я хотел бы знать, как это реализовать, когда ваши ключи используются в качестве индексных переменных в цикле. - person CodeKingPlusPlus; 19.04.2013

R-матрицы позволяют это сделать. Есть как разреженный, так и плотный вариант. Я считаю, что tm-package использует вариант разреженных матриц для формирования своей реализации словарей. Это показывает, как извлечь элементы [i,j] матрицы M, где [i,j] представлен как матрица с двумя столбцами.

M<- matrix(1:20, 5, 5)
ij <- cbind(sample(1:5), sample(1:5) )

> ij
     [,1] [,2]
[1,]    4    4
[2,]    1    2
[3,]    5    3
[4,]    3    1
[5,]    2    5
> M[ij]
[1] 19  6 15  3  2

@Justin также указывает, что вы можете использовать списки, которые можно индексировать по положению:

 L <- list( as.list(letters[1:5] ), as.list( paste(2,letters[1:5] ) ) )

> L[[1]][[2]]
[1] "b"
> L[[2]][[2]]
[1] "2 b"
person IRTFM    schedule 18.04.2013