Каковы эквиваленты R для этих пониманий списков Python:
[(i,j) for i,j in zip(index, Values)]
[(i,j) for i,j in enumerate(Values)]
[(i,j) for i,j in enumerate(range(10,20))] %MWE, indexing or enumerating to
%keep up with the index, there may
%be some parameter to look this up
Пример с выводом
>>> [(i,j) for i,j in enumerate(range(10,20))]
[(0, 10), (1, 11), (2, 12), (3, 13), (4, 14), (5, 15), (6, 16), (7, 17), (8, 18), (9, 19)]
Я решил эту проблему ранее с помощью некоторого трюка в R, но больше не могу вспомнить, первой идеей было itertools -pkg, но я надеюсь найти более идиоматический способ сделать что-то.
expand.grid(i=10:20,j=10:20)
as.vector(rbind(1:10, 11:20))
Ответы:
Ответ для питона
enumerate
:В R список упорядочен (см. Этот ответ ). Таким образом, все, что вам нужно, это проиндексировать либо ключи (используя
names()[i]
), либо значения (используя[[i]]
).Использование
seq_along
(в качестве альтернативы можно сделатьfor(i in 1:length(mylist)){...}
):> mylist <- list('a'=10,'b'=20,'c'=30) > for (i in seq_along(mylist)){ + print(paste(i,names(mylist)[i],mylist[[i]])) + } [1] "1 a 10" [1] "2 b 20" [1] "3 c 30"
Ответ для питона
zip
:См. Один из приведенных выше ответов, чтобы имитировать список кортежей. Я предпочитаю фрейм данных, как показано в ответе BondedDust:
> x <- 1:3 > y <- 4:6 > data.frame(x=x, y=y) x y 1 1 4 2 2 5 3 3 6
источник
data.frame(names=labels(mylist),values=unlist(mylist),row.names = 1:length(mylist))
Были некоторые дискуссии по поводу понимания списков для R, например, здесь или там . Хэш - пакет даже предлагает словарь структуры. Однако, как говорили другие, трудно попытаться сопоставить возможности одного языка с другим (даже если это то, что на самом деле предлагает Сравнение языков программирования ) без четкого понимания того, для чего он должен использоваться. Например, я могу имитировать Python
zip()
в R следующим образом:Python
In [1]: x = [1,2,3] In [2]: y = [4,5,6] In [3]: zip(x, y) Out[3]: [(1, 4), (2, 5), (3, 6)]
р
> x <- 1:3 > y <- 4:6 > list(x, y) # gives a simple list > as.list(paste(x, y)) # three tuples, as a list of characters > mapply(list, x, y, SIMPLIFY=F) # gives a list of 3 tuples > rbind(x, y) # gives a 2x3 matrix
Как видно, это действительно зависит от того, что вы хотите делать с результатом впоследствии.
источник
mapply
то, что мы хотим от прямого аналога.mapply
охватывает наиболее распространенный вариант использования: zip, затем map.Другой вариант, который создаст список векторов, - использовать функцию Map, как показано здесь @peterhurford: https://rdrr.io/github/peterhurford/funtools/src/R/zippers.R
> x <- 1:3 > y <- 4:6 > z <- 7:9 > Map(c, x, y, z)
[[1]] [1] 1 4 7 [[2]] [1] 2 5 8 [[3]] [1] 3 6 9
источник
for xi, yi in zip(x, y): ...
. +1 за самое элегантное решение, которое я видел до сих пор, чтобы сделать это в R:for (xi.yi in Map(c, x, y)) { xi <- xi.yi[1]; yi <- xi.yi[2]; ... }
Если это печатное представление матрицы Python, то этот код:
j <- 10:20 matrix(c(seq_along(j), j), ncol=2) #------------ [,1] [,2] [1,] 1 10 [2,] 2 11 [3,] 3 12 [4,] 4 13 [5,] 5 14 [6,] 6 15 [7,] 7 16 [8,] 8 17 [9,] 9 18 [10,] 10 19 [11,] 11 20
Вы по-прежнему оставляете в неведении тех из нас, кто не является пользователем Python, в отношении структуры желаемого результата. Вы используете термин «список», но вывод предлагает упорядоченный набор кортежей.
Учитывая руководство @ chi, мы также можем предложить использовать очень R-центрическую структуру dataframe.
x <- 1:3 y <- 4:6 dfrm <- data.frame(x=x, y=y)
... который обладает гибкостью списка с точки зрения типов столбцов и функциями доступа матрицы с точки зрения индексации строк и столбцов. Или можно использовать запрос hhh и создать неявно проиндексированные значения j-вектора,
10:20
используяrownames
вектор, который по умолчанию начинается с «1», но который может быть изменен, чтобы стать вектором символов, начинающимся с «0»dfrm <- data.frame(j=10:20) dfrm[3, ] #[1] 12 rownames(dfrm) <- 0:10 dfrm["0",] # [1] 10
К сожалению, неосторожные люди обнаружат, что dfrm [0,] не является удачным вызовом, возвращающим вектор длины 0.
источник
Чтобы использовать понимание списков в стиле Python с перечислениями, такими как нумерованные списки, одним из способов является установка пакета List-
LC
complationion (разработан в 2018 г.) и пакета itertools (разработан в 2015 г.).Составить список в R
Вы можете найти
LC
пакет здесь .install.packages("devtools") devtools::install_github("mailund/lc")
пример
> library(itertools); library(lc) > lc(paste(x$index, x$value), x=as.list(enumerate(rnorm(5))), ) [[1]] [1] "1 -0.715651978438808" [[2]] [1] "2 -1.35430822605807" [[3]] [1] "3 -0.162872340884235" [[4]] [1] "4 1.42909760816254" [[5]] [1] "5 -0.880755983937781"
где синтаксис программирования еще не так чист и отполирован, как в Python, но функционально работает, и его справочная информация:
где обратите внимание, что вы можете оставить предикаты пустыми, например, в приведенном выше примере.
Инструменты itertools и перечисления в стиле Python
Вы можете использовать itertools R, который очень похож на itertools Python, далее в Cran здесь
где описано
Пример. перечисление
> for (a in as.list(enumerate(rnorm(5)))) { print(paste(a$index, "index:", a$value))} [1] "1 index: 1.63314811372568" [1] "2 index: -0.983865948988314" [1] "3 index: -1.27096072277818" [1] "4 index: 0.313193212706331" [1] "5 index: 1.25226639725357"
Пример. перечисление с помощью ZIP
> for (h in as.list(izip(a=1:5, b=letters[1:5]))) { print(paste(h$a, "index:", h$b))} [1] "1 index: a" [1] "2 index: b" [1] "3 index: c" [1] "4 index: d" [1] "5 index: e"
источник
zip
иenumerate
не особо сложно реализовать в R:#' zip(1:5,1:10) zip <- function(...) { mapply(list, ..., SIMPLIFY = FALSE) }
Enumerate просто определить с точки зрения
zip
:#' enumerate(l=LETTERS) enumerate <- function(...) { zip(ix=seq_along(..1), ...) }
Поскольку это правильные функции, мы можем использовать их,
...
чтобы сделать их довольно гибкими и краткими, а также воспользоваться поведением mapply, например, повторным использованием входных данных и правильным присвоением имен выходным данным.источник
stackoverflow
пакет, fwiw.# similar to python. return a list of list. Short sequences get recycled. zip <- function(...){ all.list <- list(...) ele.names <- names(all.list) max.length <- max(sapply(all.list, length)) lapply(0:(max.length - 1), function(i) { res <- lapply(all.list, function(l) l[i %% length(l) + 1]) names(res) <- ele.names res }) }
источник
Этого можно добиться с помощью двух операторов вставки:
str1 <- paste(1:11, 10:20, sep=",", collapse='), (') paste("(", str1, ")", sep = "")
На выходе получится следующее:
'(1,10), (2,11), (3,12), (4,13), (5,14), (6,15), (7,16), (8,17), (9,18), (10,19), (11,20)'
источник
Для python эквивалент 'enumerate' в R. Сохранение векторов в списке и итерация по ним с индексом должны работать нормально.
vect1 <- c('A', 'B', 'C') vect2 <- c('a', 'b', 'c') # eqiv to zip values: idx_list <- list(vect1, vect2) idx_vect <- c(1:length(idx_list[[1]])) for(i in idx_vect){ x <- idx_list[[1]][i] j <- idx_list[[2]][i] print(c(i, x, j)) }
Вывод:
[1] "1" "A" "a" [1] "2" "B" "b" [1] "3" "C" "c"
R 'list' - хороший банк для хранения векторов и индексации.
источник