Отображение / перебор списков разных размеров в R - PullRequest
0 голосов
/ 28 июня 2019

У меня есть два списка разной длины, и я хотел бы сгенерировать все перестановки для запуска через функцию в R. Я могу сделать это с помощью цикла for (см. Ниже), но мне не нравится использовать rbind иcbind.Я не смог заставить его работать с *apply или purrr функциями, такими как map2, потому что они жалуются на неравную длину.

Какой самый чистый способ сделать это удобнее для работы с Tidyverse?

Упрощенный пример ниже:

myfun = function(a,b){
    return(a*b)
}
xvalues = c(1,2,3)
yvalues = c(10,20,30,40)

merged = c()
for (x in xvalues){
    z = myfun(x,yvalues)
    merged = rbind(merged,(cbind(x,yvalues,z)))
}

df = data.frame(merged)

Это создает желаемый фрейм данных:

   x yvalues   z
1  1      10  10
2  1      20  20
3  1      30  30
4  1      40  40
5  2      10  20
6  2      20  40
7  2      30  60
8  2      40  80
9  3      10  30
10 3      20  60
11 3      30  90
12 3      40 120

Ответы [ 2 ]

2 голосов
/ 28 июня 2019

Вы можете использовать семейство функций cross, например, cross_df, чтобы сгенерировать набор списков продуктов в ситуациях, когда вы хотите выполнить итерацию по всем комбинациям.Это позволяет затем использовать map функции как обычно:

library(tidyverse)
myfun = function(a,b){
  return(a*b)
}
xvalues = c(1,2,3)
yvalues = c(10,20,30,40)

cross_df(list(x = xvalues, y = yvalues)) %>%
  mutate(z = map2_dbl(x, y, myfun))
#> # A tibble: 12 x 3
#>        x     y     z
#>    <dbl> <dbl> <dbl>
#>  1     1    10    10
#>  2     2    10    20
#>  3     3    10    30
#>  4     1    20    20
#>  5     2    20    40
#>  6     3    20    60
#>  7     1    30    30
#>  8     2    30    60
#>  9     3    30    90
#> 10     1    40    40
#> 11     2    40    80
#> 12     3    40   120

Конечно, в этом случае myfun векторизовано, поэтому использование map не совсем необходимо.

cross_df(list(x = xvalues, y = yvalues)) %>%
  mutate(z = myfun(x, y))
#> # A tibble: 12 x 3
#>        x     y     z
#>    <dbl> <dbl> <dbl>
#>  1     1    10    10
#>  2     2    10    20
#>  3     3    10    30
#>  4     1    20    20
#>  5     2    20    40
#>  6     3    20    60
#>  7     1    30    30
#>  8     2    30    60
#>  9     3    30    90
#> 10     1    40    40
#> 11     2    40    80
#> 12     3    40   120

Создано в 2019-06-28 пакетом Представ (v0.3.0)

1 голос
/ 28 июня 2019

С base R мы можем использовать expand.grid

transform(expand.grid(x= xvalues, yvalues = yvalues), z = myfun(x, yvalues))
#   x yvalues   z
#1  1      10  10
#2  2      10  20
#3  3      10  30
#4  1      20  20
#5  2      20  40
#6  3      20  60
#7  1      30  30
#8  2      30  60
#9  3      30  90
#10 1      40  40
#11 2      40  80
#12 3      40 120

Или используя data.table

library(data.table)
CJ(x= xvalues, yvalues)[, z := myfun(x, yvalues)][]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...