Один вкладыш для декартовой системы двух векторов с заданными именами colrings и stringsAsFactors = FALSE в R - PullRequest
0 голосов
/ 05 ноября 2018

Я хотел бы сделать декартову из двух векторов в R, что

  1. Возвращает data.frame с именами столбцов
  2. Возвращает символьные столбцы вместо факторов

Конечно, я могу сделать это в несколько строк кода.

df <- merge(1:3, letters[1:3], all = TRUE)
colnames(df) <- c("number", "letter")
df$letter <- as.character(df$letter)
str(df)
## 'data.frame':    9 obs. of  2 variables:
##  $ number: int  1 2 3 1 2 3 1 2 3
##  $ letter: chr  "a" "a" "a" "b" ...

Но в идеале это должен быть однострочный код, такой как приведенный ниже код (который не дает желаемого результата).

df2 <- merge(c(number = 1:3),
             c(letter = letters[1:3]), all = TRUE, stringsAsFactors = FALSE)
str(df2)
## 'data.frame':    9 obs. of  2 variables:
##  $ x: int  1 2 3 1 2 3 1 2 3
##  $ y: Factor w/ 3 levels "a","b","c": 1 1 1 2 2 2 3 3 3

У кого-нибудь есть однострочники, которые могли бы работать на этом пределе? Рады также принять решения dplyr и data.table. Идеальное решение показало бы, предоставить одну строку для каждого base, dplyr и data.table.

Ответы [ 3 ]

0 голосов
/ 05 ноября 2018

expand.grid обычно используется в подобных случаях. Он хорошо обобщается, используйте do.call, чтобы использовать его на list векторов для расширения.

res = expand.grid(
   numbers = 1:3,
   letters = c('a', 'b', 'c'),
   stringsAsFactors = FALSE)

head(res)
#   numbers letters
# 1       1       a
# 2       2       a
# 3       3       a
# 4       1       b
# 5       2       b
# 6       3       b

str(res)
# 'data.frame': 9 obs. of  2 variables:
#  $ numbers: int  1 2 3 1 2 3 1 2 3
#  $ letters: chr  "a" "a" "a" "b" ...
#  - attr(*, "out.attrs")=List of 2
#   ..$ dim     : Named int  3 3
#   .. ..- attr(*, "names")= chr  "numbers" "letters"
#   ..$ dimnames:List of 2
#   .. ..$ numbers: chr  "numbers=1" "numbers=2" "numbers=3"
#   .. ..$ letters: chr  "letters=a" "letters=b" "letters=c"
0 голосов
/ 05 ноября 2018

Все ответы здесь великолепны. Просто добавьте к ним, tidyr имеет функцию crossing, которая также будет соответствовать вашим потребностям.

> tidyr::crossing(numbers = 1:3, letters = letters[1:3])
# A tibble: 9 x 2
  numbers letters
    <int> <chr>  
1       1 a      
2       1 b      
3       1 c      
4       2 a      
5       2 b      
6       2 c      
7       3 a      
8       3 b      
9       3 c 
0 голосов
/ 05 ноября 2018

help("merge") говорит

Аргументы

x, y фреймы данных или объекты, которые должны быть приведены к одному.

Это намекает на решение:

df2 <- merge(data.frame(number = 1:3),
             data.frame(letter = letters[1:3], stringsAsFactors = FALSE), all = TRUE)
str(df2)
#'data.frame':  9 obs. of  2 variables:
# $ number: int  1 2 3 1 2 3 1 2 3
# $ letter: chr  "a" "a" "a" "b" ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...