在 R 中设置了 colnames 和 stringsAsFactors = FALSE 的两个向量的笛卡尔的一个衬垫
One liner for cartesian of two vectors with colnames set and stringsAsFactors = FALSE in R
我想在 R 中做两个向量的笛卡尔坐标
- Returns
data.frame
列名
- 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 上工作的单行代码吗?也很高兴接受 dplyr
和 data.table
解决方案。理想的解决方案是为每个 base
、dplyr
和 data.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.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"
这里大家的回答都很棒。补充一下,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
我想在 R 中做两个向量的笛卡尔坐标
- Returns
data.frame
列名 - 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 上工作的单行代码吗?也很高兴接受 dplyr
和 data.table
解决方案。理想的解决方案是为每个 base
、dplyr
和 data.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.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"
这里大家的回答都很棒。补充一下,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