用基数R循环多个列表

时间:2017-09-13 19:29:55

标签: r

在python中我们可以做到这一点..

numbers = [1, 2, 3]
characters = ['foo', 'bar', 'baz']

for item in zip(numbers, characters):
    print(item[0], item[1])

(1, 'foo')
(2, 'bar')
(3, 'baz')

我们也可以解压缩元组而不是使用索引。

for num, char in zip(numbers, characters):
    print(num, char)

(1, 'foo')
(2, 'bar')
(3, 'baz')

我们如何使用基数R来做同样的事情?

7 个答案:

答案 0 :(得分:2)

要索引R中的向量,其中向量是变量x将是x [1]。这将返回向量的第一个元素。 R元素编号从1开始,而Python则从0开始。

对于这个问题,它将是:

x = seq(1,10)
j = seq(11,20)

for (i in 1:length(x)){

    print (c(x[i],j[i]))
}

答案 1 :(得分:2)

R中的许多函数都是矢量化的,不需要循环:

numbers = c(1, 2, 3)
characters = c('foo', 'bar', 'baz')
myList <- list(numbers, characters)
myDF <- data.frame(numbers,characters, stringsAsFactors = F)

print(myList)
print(myDF)

答案 2 :(得分:2)

要以R-native方式执行此类操作,您将使用数据框架的概念。数据框有多个变量,可以是不同的类型,每行都是对每个变量的观察。

d <- data.frame(numbers = c(1, 2, 3),
                characters = c('foo', 'bar', 'baz'))
d
##   numbers characters
## 1       1        foo
## 2       2        bar
## 3       3        baz

然后使用矩阵表示法访问每一行,其中将索引留空包括所有内容。

d[1,]
##   numbers characters
## 1       1        foo

然后你可以遍历数据框的各行来做任何你想做的事情,可能你真的想做一些比打印更有趣的事情。

for(i in seq_len(nrow(d))) {
  print(d[i,])
}
##   numbers characters
## 1       1        foo
##   numbers characters
## 2       2        bar
##   numbers characters
## 3       3        baz

答案 3 :(得分:2)

对于另一个选项,mapply怎么样,这是我在R中可以想到的最接近的zip模拟。这里我使用c函数来创建一个新的向量,但你可以使用你想要的任何功能:

numbers<- c(1, 2, 3)
characters<-  c('foo', 'bar', 'baz')
mapply(c,numbers, characters, SIMPLIFY = FALSE)

[[1]]
[1] "1"   "foo"

[[2]]
[1] "2"   "bar"

[[3]]
[1] "3"   "baz"

哪种方式最常用取决于你想要对输出做什么,但正如其他答案所提到的,数据帧是R中最自然的方法(可能是python中的pandas数据帧)。

答案 4 :(得分:0)

这是概念上的等价物:

for (item in Map(list,numbers,characters)){ # though most of the time you would actually do all your work inside Map
  print(item[c(1,2)])
}

# [[1]]
# [1] 1
# 
# [[2]]
# [1] "a"
# 
# [[1]]
# [1] 2
# 
# [[2]]
# [1] "b"
# 
# [[1]]
# [1] 3
# 
# [[2]]
# [1] "c"
# 
# [[1]]
# [1] 4
# 
# [[2]]
# [1] "d"
# 
# [[1]]
# [1] 5
# 
# [[2]]
# [1] "e"

虽然大部分时间你都会在Map中完成所有工作并做类似的事情:

Map(function(nu,ch){print(data.frame(nu,ch))},numbers,characters)

这是我最接近克隆的地方:

zip <- function(...){ Map(list,...)}
print2 <- function(...){do.call(cat,c(list(...),"\n"))}

for (item in zip(numbers,characters)){
  print2(item[[1]],item[[2]])
}

# 1 a 
# 2 b 
# 3 c 
# 4 d 
# 5 e

能够按名称调用项目(仍可使用索引):

zip <- function(...){
  names <- sapply(substitute(list(...))[-1],deparse)
  Map(function(...){setNames(list(...),names)}, ...)
}

for (item in zip(numbers,characters)){
  print2(item[["numbers"]],item[["characters"]])
}

答案 5 :(得分:0)

tidyverse解决方案是使用purrr::map2函数。例如:

numbers <- c(1, 2, 3)
characters <- c('foo', 'bar', 'baz')

map2(numbers, characters, ~paste0(.x, ',', .y))

#[[1]]
#[1] "1,foo"

#[[2]]
#[1] "2,bar"

#[[3]]
#[1] "3,baz"

请参阅API here

答案 6 :(得分:0)

其他可扩展的替代方案:将向量存储在列表中并进行迭代。

vect1 <- c(1, 2, 3)
vect1 <- c('foo', 'bar', 'baz')
vect2 <- c('a', 'b', 'c')


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