通过函数式编程消除循环循环

时间:2018-11-26 05:48:20

标签: r for-loop lapply

我想从具有systemName变量和popNum变量的数据帧中获取输入,并使用它生成元素为随机数(1- 6)* 5 ,即(5、10、15、20、25、30),其中向量长度等于系统的popNum。

以下代码有效:

## Data
#Create a vector of integers
popNum <- c (2,5,3,9)
#Create corresponding names
systemNames <- c("Ruie", "Regina", "Roupe", "Efate")
# form up into a recatangular data frame
dataSource <- cbind.data.frame(systemNames,popNum )

## Create and Fill the List
#initialise the list
availableCargoes <- vector( mode = "list", length = nrow(dataSource))

#name the list
names(availableCargoes) <- dataSource$systemNames

#fill the list 
for (loopCounter in 1:nrow(dataSource)) {
availableCargoes[[loopCounter]] <- sample.int( n = 6, 
                                             size = dataSource$popNum[loopCounter],
                                             replace = TRUE) * 5
}

如何通过apply系列或purrr软件包中的内容摆脱for循环?我很难解决的问题是X运行lapply的{​​{1}}是什么?如何传递sample.int的向量作为参数来控制所得向量的大小?

2 个答案:

答案 0 :(得分:1)

使用lapply直接遍历dataSource$popNum
请注意,我设置了RNG种子以使结果可重复。

set.seed(1234)
for (loopCounter in 1:nrow(dataSource)) {
  availableCargoes[[loopCounter]] <- sample.int( n = 6, 
                                                 size = dataSource$popNum[loopCounter],
                                                 replace = TRUE) * 5
}

set.seed(1234)
ac <- lapply(dataSource$popNum, function(s) 
  sample.int(n = 6, size = s, replace = TRUE)*5)
names(ac) <- dataSource$systemNames
ac

identical(availableCargoes, ac)
#[1] TRUE

答案 1 :(得分:1)

适用版本

## Data
#Create a vector of integers
popNum <- c (2,5,3,9)
#Create corresponding names
systemNames <- c("Ruie", "Regina", "Roupe", "Efate")
# form up into a recatangular data frame
dataSource <- cbind.data.frame(systemNames,popNum )

## Create and Fill the List
#initialise the list
availableCargoes <- vector( mode = "list", length = nrow(dataSource))

#name the list
names(availableCargoes) <- dataSource$systemNames

#fill the list 

availableCargoes <- sapply(as.character(dataSource$systemNames),function(sysname){

  sample.int( n = 6, 
              size = dataSource$popNum[dataSource$systemNames==sysname],
              replace = TRUE) * 5
},USE.NAMES=T,simplify = F)