在 R 中设置了 colnames 和 stringsAsFactors = FALSE 的两个向量的笛卡尔的一个衬垫

One liner for cartesian of two vectors with colnames set and stringsAsFactors = FALSE in R

我想在 R 中做两个向量的笛卡尔坐标

  1. Returns data.frame 列名
  2. Returns 字符列而不是因子

我当然可以用几行代码做到这一点。

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

有人有可以在这个 reprex 上工作的单行代码吗?也很高兴接受 dplyrdata.table 解决方案。理想的解决方案是为每个 basedplyrdata.table.

提供一行

help("merge")

Arguments

x, y data frames, or objects to be coerced to one.

这暗示了解决方案:

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" ...

expand.grid常用于这种情况。它概括得很好,使用 do.calllist 向量上使用它来扩展。

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"

这里大家的回答都很棒。补充一下,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