web-dev-qa-db-ja.com

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でしたが、もっと慣用的な方法を見つけることを望んでいます。

65
hhh

Rのリストの理解に関する議論がいくつかありました。 here または therehash パッケージは、辞書のような構造も提供します。しかし、他の人が言ったように、使用するものを明確に理解せずに、ある言語機能を別の言語機能にマップすることは困難です(これが プログラミング言語の比較 が実際に提供するものであっても)に。たとえば、次のようにRのPython Zip()を模倣できます。

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)]

[〜#〜] r [〜#〜]

> 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 

見てわかるように、これは後で結果をどうするかによって異なります。

36
chl

python enumerate

Rでは、リストが順序付けられます( this answer を参照)。したがって、必要なのは、キー(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"
_

python 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
_
33
Theja

それが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中心の「データフレーム」構造を使用することもお勧めします。

x <- 1:3
y <- 4:6
dfrm <- data.frame(x=x, y=y)

...これには、列の種類の点でリストの柔軟性があり、行と列のインデックス付けの点でマトリックスのアクセス機能があります。または、hhhの要求を使用して、jベクトルの暗黙的にインデックス付けされた値10:20、デフォルトでは「1」で始まるrownamesベクトルを使用しますが、「0」で始まる文字ベクトルになるように変更できます

dfrm <- data.frame(j=10:20)
dfrm[3, ]
#[1] 12

 rownames(dfrm) <- 0:10
 dfrm["0",]
# [1] 10

残念ながら、不注意な人はdfrm [0、]は幸せな呼び出しではなく、長さ0のベクトルを返すことに気付くでしょう。

5
42-

Python列挙リストなどの列挙を持つスタイルリスト内包表記を使用するには、1つの方法は、List-comprehensionパッケージLC(開発済み2018)およびitertoolsパッケージ(開発済み2015 )。

Rの内包表記

LCパッケージを見つけることができます here

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のようにきれいで洗練されていませんが、機能的に機能し、そのヘルプの概要は次のとおりです。

「構文は次のとおりです。lc(expr、lists、predicates)exprはリスト内のすべての要素に対して評価される式です。listは1つ以上の名前付きリストで、名前と式名で指定されます。 = list_expr、および述語はブール値に評価される式です。たとえば、リストxからすべての偶数のリストを取得するには、lc(x ** 2、x = x、x%と書くことができます。 %2 == 0)。lcの呼び出しの結果は、述語がtrueと評価される入力リストのすべての要素について、exprの式から構築されたリストです。

上記の例のように、述部を空のままにできることに注意してください。

Pythonスタイルのitertoolsと列挙

Pythonのitertoolsに非常によく似たRのitertoolsを使用できます。さらにCranで here

library(itertools)

説明したところ

「イテレータを作成するためのさまざまなツール、Python itertoolsモジュールのパターン化された関数の多く、および 'snow'パッケージの関数のパターン化された他の要素。 "

例。列挙

> 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"
2
hhh

ベクトルのリストを作成する別のオプションは、@ peterhurfordがここで見られるようにMap関数を使用することです。 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
2
wphampton
# 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
    })
}
0
Leaf

Zipenumerateは、Rでの実装は特に難しくありません。

#' Zip(1:5,1:10)
Zip <- function(...) {
  mapply(list, ..., SIMPLIFY = FALSE)
}

列挙は、Zipに関して簡単に定義できます。

#' enumerate(l=LETTERS)
enumerate <- function(...) {
  Zip(ix=seq_along(..1), ...)
}

これらは適切な関数であるため、...を使用してかなり柔軟で簡潔にし、入力のリサイクルや出力の命名など、mapplyの動作を活用できます。

0
Neal Fultz