如何轻松生成此序列?
c(1,2,1,3,1,4,1,5,1,6,1,7,1,8,1,9,1,10,
2,3,2,4,2,5,2,6,2,7,2,8,2,9,2,10)
有没有简单的方法来写这个?
答案 0 :(得分:6)
我想你想要像
这样的东西$cnt=10000;
for($i=0;$i<$cnt;$i++) {
$array[]['key1'] = 1;
$array[]['key2'] = 2;
$array[]['key3'] = 3;
}
/*array_walk($array, function (&$item,$key) {
$item['key4'] = 1;
$item['key5'] = 1;
$item['key6'] = 1;
}); //memory used PHP7/PHP5: 13 437 720 - 25 924 944 */
/*$map = array_map(function (array $item) {
$item['key4'] = 1;
$item['key5'] = 1;
$item['key6'] = 1;
return $item;
}, $array); //memory used PHP7/PHP5: 25 050 360 - 40 850 480*/
作为数据框
t(combn(1:10, 2))
# [,1] [,2]
# [1,] 1 2
# [2,] 1 3
# [3,] 1 4
# [4,] 1 5
# [5,] 1 6
# [6,] 1 7
# [7,] 1 8
# [8,] 1 9
# [9,] 1 10
# [10,] 2 3
# [11,] 2 4
# [12,] 2 5
# [13,] 2 6
# [14,] 2 7
# [15,] 2 8
# [16,] 2 9
# [17,] 2 10
# etc
答案 1 :(得分:5)
这是部分 - dplyr
解决方案。 (当然,使用filter()
的替换并且不使用管道是微不足道的......)expand.grid
通常适用于此,但在这种情况下,它比CPak使用的更复杂一点combn
因为我们必须切换列顺序:
expand.grid(1:10, 1:10) %>% rev %>% filter(Var2 < Var1) %>% t %>% as.vector
[1] 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 2 3 2 4 2 5 2 6 2
[28] 7 2 8 2 9 2 10 3 4 3 5 3 6 3 7 3 8 3 9 3 10 4 5 4 6 4 7
[55] 4 8 4 9 4 10 5 6 5 7 5 8 5 9 5 10 6 7 6 8 6 9 6 10 7 8 7
[82] 9 7 10 8 9 8 10 9 10
添加base
方法:
n = 10
unlist(lapply(1:(n - 1), FUN = function(x) as.vector(rbind(x, (x + 1):n))))
对于大n,我希望这会快得多,因为它根本不使用数据帧,不会生成不需要的组合,然后将它们过滤掉。
答案 2 :(得分:3)
这是一种base R
方式。
fun <- function(x, k) c(k, x)
n <- 10
res <- lapply(seq_len(n - 1), function(k) sapply((k + 1):n, fun, k))
unlist(lapply(res, c))
# [1] 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 2 3 2 4 2 5 2
#[26] 6 2 7 2 8 2 9 2 10 3 4 3 5 3 6 3 7 3 8 3 9 3 10 4 5
#[51] 4 6 4 7 4 8 4 9 4 10 5 6 5 7 5 8 5 9 5 10 6 7 6 8 6
#[76] 9 6 10 7 8 7 9 7 10 8 9 8 10 9 10
答案 3 :(得分:2)
这是一个使用基数R的小功能,允许您控制起始值和停止值。
combos <- function(x, y) unlist(Map(rbind, as.list(1:x), lapply(2:(x+1), ":", y)))
combos(3, 10)
[1] 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 2 3 2 4 2 5 2 6 2
[28] 7 2 8 2 9 2 10 3 4 3 5 3 6 3 7 3 8 3 9 3 10
combos(2, 5)
[1] 1 2 1 3 1 4 1 5 2 3 2 4 2 5
combos(3, 5)
[1] 1 2 1 3 1 4 1 5 2 3 2 4 2 5 3 4 3 5
答案 4 :(得分:1)
以下是使用dplyr
和tidyr
的选项。 result
是最终输出。您可能希望进一步对result
向量进行子集化,或者根据您的需要对df2
进行子集化。在看到Gregor的回答之后,我认为我原来的方法过于复杂,因此我更新了方法如下。
library(dplyr)
library(tidyr)
dt <- data.frame(a = 1:10, b = 1:10)
dt2 <- dt %>%
complete(a, b) %>%
filter(b > a)
result <- dt2 %>%
t() %>%
as.vector()
result
[1] 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 2 3 2 4 2 5 2 6 2
[28] 7 2 8 2 9 2 10 3 4 3 5 3 6 3 7 3 8 3 9 3 10 4 5 4 6 4 7
[55] 4 8 4 9 4 10 5 6 5 7 5 8 5 9 5 10 6 7 6 8 6 9 6 10 7 8 7
[82] 9 7 10 8 9 8 10 9 10
由于行是根据列a
排序的,因此您可以根据所需的数量过滤列a
。例如,如果您只想要第一个数字不大于2.您可以对df2
dt2 <- dt %>%
complete(a, b) %>%
filter(b > a) %>%
filter(a < 3)
如上所述,使用df2
生成result
相同的代码,您将获得与示例相同的所需输出。
答案 5 :(得分:0)
我使用了for循环。如果你想要一个很长的序列,这不是你最好的选择:
# Create vectors for desired sequence
x <- 1:10
y <- 1:2
# Initiate sequence vector
seq <- c()
# Loop to fill in sequence vector
for(elem in y){
for(i in 1:length(x)){
toappend <- c(elem, x[i])
seq <- c(seq, toappend)
}
}
> print(seq)
[1] 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 2 1 2 2 2 3 2 4 2
[30] 5 2 6 2 7 2 8 2 9 2 10