R로 압축하거나 열거 하시겠습니까?


82

이 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)
같아요

@BenBolker : 출력 추가-이제 명확합니까? 더 어려울 수 있지만 논리가 중요합니다 ...
hhh

1
@DWin에 동의합니다. R과 Python의 데이터 구조간에 일대일 매핑을 기대하는 것은 비합리적입니다. 좋은 답변을 원하면 결과가 Python이 아닌 R에서 표시 되는 방식을 지정해야합니다 .
joran

그건 그렇고, 다음은 두 목록을 압축하고 평평하게 만드는 깔끔한 방법입니다.as.vector(rbind(1:10, 11:20))
smci

답변:


43

파이썬에 대한 답변 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))
요시야 Yoder 보낸 사람에게

42

R에 대한 목록 이해에 관한 몇 가지 논의 가있었습니다 . 예를 들어 here 또는 there . 해시 패키지도 사전과 같은 구조를 제공합니다. 그러나 다른 사람들이 말했듯이 ( 프로그래밍 언어 비교가 실제로 제공 하는 것이더라도) 한 언어 시설을 다른 언어 시설에 매핑 하는 것은 그것이 무엇에 사용되어야하는지에 대한 명확한 이해 없이는 어렵습니다 . 예를 들어 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 

보시다시피 이것은 나중에 결과로 무엇을 하려는지에 달려 있습니다.


1
질문은 파이썬에서 zip을 사용할 때 무엇을 사용합니까? 일반적인 사용은 여러 인수로 목록 이해를 수행하는 것이므로 mapply가 직접 처리합니다.
seanv507

6
mapply우리가 직접 아날로그 원하는 것입니다.
StephenBoesch

@javadba mapply는 가장 일반적인 사용 사례 인 zip과 map을 다룹니다.
요시야 Yoder 보낸

7

벡터 목록을 생성하는 또 다른 옵션은 @peterhurford ( https://rdrr.io/github/peterhurford/funtools/src/R/zippers.R)에서 볼 수있는 Map 함수를 사용하는 것입니다.

> 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): ...입니다.. 내가 지금까지 본 것 중 가장 우아한 솔루션을 위해 +1 R :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하는 rownames벡터를 사용하여 j- 벡터의 암시 적으로 인덱싱 된 값을 만들 수 있지만 "0"에서 시작하는 문자형 벡터로 변경 될 수 있습니다.

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

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

불행히도, dfrm [0,]은 길이가 0 인 벡터를 반환하는 행복한 호출이 아니라는 것을 알 수 있습니다.


+1은 우아한 솔루션입니다. (아니요, 그것들은 파이썬 행렬이 아니지만 이미 추측
했듯이

4

열거 형 목록과 같은 열거 형으로 Python 스타일 목록 이해를 사용하려면 한 가지 방법은 List-comprehension 패키지 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은 목록의 모든 요소에 대해 평가할 표현식입니다. 여기서 목록은 하나 이상의 명명 된 목록이며, 이름과 표현식 이름으로 지정됩니다. = list_expr, 여기서 술어는 부울 값으로 평가되어야하는 표현식입니다. 예를 들어, 목록 x에서 제곱 된 모든 짝수 목록을 얻으려면 lc (x ** 2, x = x, x % % 2 == 0). lc에 대한 호출의 결과는 술어가 참으로 평가되는 입력 목록의 모든 요소에 대해 expr의 표현식으로 구성된 목록입니다. "

위의 예에서와 같이 술어를 비워 둘 수 있습니다.

Python 스타일 itertools 및 열거 형

당신은 크랑에 추가, 파이썬의 itertools과 매우 유사 R의 itertools를 사용할 수 있습니다 여기에

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"

3

zipenumerateR에서 구현하기가 특히 어려운되지 않습니다 :

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

열거는 다음과 같이 정의하기가 간단합니다 zip.

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

이것들은 적절한 기능이기 때문에 우리는 ...그것들을 상당히 유연하고 간결하게 만들고 입력 재활용 및 출력 이름 지정과 같은 mapply의 동작을 활용할 수 있습니다.


1
이것들은 stackoverflowfwiw 패키지 에 추가되었습니다 .
Neal Fultz

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

이 코드 블록이 수행하는 작업에 대한 설명을 입력하십시오.
Keivan Esbati

이 함수는 @chl이 지적한 "mapply (list, x, y, SIMPLIFY = F)"와 똑같은
ibilgen

0

이는 두 개의 붙여 넣기 문을 사용하여 수행 할 수 있습니다.

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)'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.