在R中压缩或枚举?

hhh*_*hhh 67 indexing r enumerate

这些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
Run Code Online (Sandbox Code Playgroud)

输出示例

>>> [(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)]
Run Code Online (Sandbox Code Playgroud)

我已经用R中的一些技巧解决了这个问题,但不记得了,第一个想法是itertools -pkg,但我希望找到一种更惯用的做事方式.

chl*_*chl 38

关于R的列表理解有一些讨论,例如在这里那里.该包甚至提供类似字典的结构.然而,正如其他人所说,很难尝试将一种语言设施映射到另一种语言设施(即使这是编程语言实际提供的比较),而没有清楚地了解它应该用于什么.例如,我可以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)]
Run Code Online (Sandbox Code Playgroud)

[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 
Run Code Online (Sandbox Code Playgroud)

可以看出,这实际上取决于您之后想要对结果做什么.

  • “ mapply”是我们想要直接模拟的。 (5认同)

小智 35

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"
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

  • 如果我们想做一些超出正常语法范围的事情,R 语法就太丑陋了,这种语言在某些部分非常不灵活,但其他语言却很棒(例如 NSE 和 SE) (2认同)

wph*_*ton 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)
Run Code Online (Sandbox Code Playgroud)
[[1]]
[1] 1 4 7

[[2]]
[1] 2 5 8

[[3]]
[1] 3 6 9
Run Code Online (Sandbox Code Playgroud)


Nea*_*ltz 6

zip并且enumerate在 R 中实现并不是特别困难:

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

Enumerate 的定义很简单zip

#' enumerate(l=LETTERS)
enumerate <- function(...) {
  zip(ix=seq_along(..1), ...)
}
Run Code Online (Sandbox Code Playgroud)

由于这些是适当的函数,我们可以使用...它们来使它们相当灵活和简洁,并利用 mapply 的行为,例如正确回收输入和命名输出。


42-*_*42- 5

如果那是矩阵的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
Run Code Online (Sandbox Code Playgroud)

你仍然离开我们这些不是Python用户的人,关于你想要的输出的结构.您使用术语"列表",但输出表明一组有序的元组.

鉴于@ chi的指导,我们也可能建议使用非常以R为中心的"数据帧"结构

x <- 1:3
y <- 4:6
dfrm <- data.frame(x=x, y=y)
Run Code Online (Sandbox Code Playgroud)

...在列类型方面具有列表的灵活性,并且在行和列索引方面具有矩阵的访问特征.或者可以使用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
Run Code Online (Sandbox Code Playgroud)

不幸的是,粗心的人会发现dfrm [0,]不是一个快乐的调用,返回长度为0的向量.