Rで郵便番号または列挙しますか?


84

これらのPythonリスト内包表記に相当するRは何ですか?

[(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でしたが、もっと慣用的な方法を見つけたいと思っています。


2
Pythonに精通していない私たちのために、小さな実例を挙げていただければ、潜在的な回答者の数が増える可能性があります。最後はexpand.grid(i=10:20,j=10:20)
ベンボルカー2012

@BenBolker:出力を追加しました-クリアになりましたか?それはもっと難しいかもしれませんが、論理は重要です...
hhh 2012

1
@DWinに同意します。RとPythonのデータ構造間の1対1のマッピングを期待するのは無理です。良い答えが必要な場合は、PythonではなくRで結果をどのように表示するかを指定する必要があります。
joran 2012

ちなみに、ここでのzipにきちんとした方法だと、二つのリストをフラット化:as.vector(rbind(1:10, 11:20))
SMCI

回答:


47

Pythonの答え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"

Pythonの答えzip

タプルのリストを模倣するには、上記の回答の1つを参照してください。私の好みは、BondedDustの回答に示されているデータフレームです。

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

1
最初の例を2番目の例に続けるには、data.frame(names=labels(mylist),values=unlist(mylist),row.names = 1:length(mylist))
JosiahYoder19年

パフォーマンスに関する質問:names(mylist)[i]の呼び出しは毎回機能する必要がありますか、それとも簡単な操作ですか?それはループの前にNAME_LISTに割り当てることが最善であるかどう私は思ったんだけど
markgalassi

42

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

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 

ご覧のとおり、これは実際には、後で結果をどのように処理するかによって異なります。


1
問題は、Pythonでzipを使用するときに何を使用するかということだと思います。典型的な使用法は、複数の引数を使用してリスト内包を行うことであるため、mapplyはこれを直接処理します。
seanv507 2017年

6
これmapplyがダイレクトアナログに必要なものです。
StephenBoesch 2018年

@javadbamapplyは、最も一般的なユースケースであるzip、次にmapをカバーしています。
JosiahYoder19年

8

ベクトルのリストを作成する別のオプションは、@ 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

Pythonでは、zipの主な用途は、いくつかのベクトル/リストに対する反復ですfor xi, yi in zip(x, y): ...。私はRでこれを行うには、これまで見た中で最もエレガントなソリューションのための+1:for (xi.yi in Map(c, x, y)) { xi <- xi.yi[1]; yi <- xi.yi[2]; ... }
sgrubsmyon

6

それが行列の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の要求を使用し、デフォルトで「1」で始まるベクトルを10:20使用して、j-vectorの暗黙的にインデックス付けされた値を作成rownamesできますが、「0」で始まる文字ベクトルになるように変更できます。

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

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

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


エレガントなソリューションのための+1。(いいえ、これらはPythonマトリックスではありませんが、すでにお
察しのとおり

4

列挙型リストなどの列挙型でPythonスタイルのリスト内包表記を使用するには、1つの方法は、リスト内包表記パッケージLC(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ほどクリーンで洗練されていませんが、機能的に機能しており、そのヘルプの概要は次のとおりです。

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

ここで、たとえば上記の例では、述語を空のままにしておくことができることに注意してください。

Pythonスタイルのitertoolsと列挙

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

library(itertools)

説明されている場所

「イテレータを作成するためのさまざまなツール。多くはPythonitertoolsモジュールの関数の後にパターン化され、その他は「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"

4

zipそしてenumerateRで実施するのが特に困難ではありません。

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

列挙は、次の点で簡単に定義できますzip

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

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


1
これらはstackoverflowパッケージfwiwに追加されました。
ニールフルツ

0
# 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
    })
}

このコードブロックの機能について説明してください。
KeivanEsbati18年

この機能は、尖った@chl「mapply(リスト、X、Y、簡素化= F)」とまったく同じことをする
ibilgen

0

これは、2つの貼り付けステートメントを使用して実現できます。

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

0

Pythonの場合、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 'は、ベクトルをデポジットし、インデックスを保持するための優れたバンクです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.