Nice programing

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

nicepro 2020. 11. 18. 21:30
반응형

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


이 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 이었지만 더 관용적 인 방법을 찾고 싶습니다.


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 

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


파이썬에 대한 답변 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

이것이 행렬의 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 인 벡터를 반환하는 행복한 호출이 아니라는 것을 알 수 있습니다.


벡터 목록을 생성하는 또 다른 옵션은 @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

In order to use Python style list comprehensions with enumerations, such as enumerated lists, one way is to install List-comprehension package LC (developed 2018) and itertools package (developed 2015).

List comprehensions in R

You can find the LC package here.

install.packages("devtools")
devtools::install_github("mailund/lc")

Example

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

where the programming syntax is not yet as clean and polished as in Python but functionally working and its help outlines:

"The syntax is as follows: lc(expr, lists, predicates) where expr is some expression to be evaluated for all elements in the lists, where lists are one or more named lists, where these are specified by a name and an expression name = list_expr, and where predicates are expressions that should evaluated to a boolean value. For example, to get a list of all even numbers, squared, from a list x we can write lc(x ** 2, x = x, x %% 2 == 0). The result of a call to lc is a list constructed from the expressions in expr, for all elements in the input lists where the predicates evaluate to true."

where notice that you can leave the predicates empty for example in the above example.

Python-style itertools and enumerations

You can use R's itertools that is very similar to Python's itertools, further in Cran here

library(itertools)

where described

"Various tools for creating iterators, many patterned after functions in the Python itertools module, and others patterned after functions in the 'snow' package."

Example. enumeration

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

Example. enumeration with 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 and enumerate are not particularly difficult to implement in R:

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

Enumerate is simple to define in terms of zip:

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

Since these are proper functions, we can use ... to make them fairly flexible and terse, and take advantage of mapply's behavior, such as recycling inputs and naming output correctly.


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

참고URL : https://stackoverflow.com/questions/9281323/zip-or-enumerate-in-r

반응형