在添加列

时间:2018-12-07 17:01:39

标签: r

这是我的可复制代码:

df <- data.frame(x = c(1, 2), y = c(3, 4))

df1 <- df %>% mutate(z = 1)
df2 <- df %>% mutate(z = 2)
df3 <- df %>% mutate(z = 3)

df <- rbind(df1, df2, df3)

df

我将原始数据帧df重复3次,同时添加一列,其中列中的数字表示重复。在我的用例中,我必须执行3次以上。我可以使用循环,但是有更整洁的方法吗?我想我不能使用expand.grid。

5 个答案:

答案 0 :(得分:5)

您也可以使用merge来做到这一点:

dfz <- data.frame(z = 1:3)

merge(df, dfz)

#   x y z
# 1 1 3 1
# 2 2 4 1
# 3 1 3 2
# 4 2 4 2
# 5 1 3 3
# 6 2 4 3

答案 1 :(得分:3)

我们可以创建一个list列和unnest

library(tidyverse)
df %>%
   mutate(z = list(1:3)) %>%
   unnest %>%
   arrange(z)
#  x y z
#1 1 3 1
#2 2 4 1
#3 1 3 2
#4 2 4 2
#5 1 3 3
#6 2 4 3

答案 2 :(得分:3)

我们还可以使用"Timer duration: " & timerDuration 进行交叉联接。这将创建sqldfdf表的笛卡尔乘积:

reps

或仅使用library(sqldf) reps <- data.frame(z = 1:3) sqldf("select * from df, reps order by z") 中的map_dfr

purrr

输出:

library(purrr)

map_dfr(1:3, ~cbind(df, z = .))

答案 3 :(得分:1)

还可以使用base R

n <- 3
do.call(rbind, 
        Map(`[<-`, replicate(n = n, 
                             expr = df, 
                             simplify = FALSE), 
            "z", 
            value = seq_len(n)))
#  x y z
#1 1 3 1
#2 2 4 1
#3 1 3 2
#4 2 4 2
#5 1 3 3
#6 2 4 3

答案 4 :(得分:1)

尚未涵盖的其他几种方式:

# setup
df = data.frame(x = c(1, 2), y = c(3, 4))
n = 3

# simple row indexing, add column manually
result = df[rep(1:nrow(df), 3), ]
result$id = rep(1:n, each = nrow(df))

# cross join in base
merge(df, data.frame(id = 1:n), by = NULL)

# cross join in tidyr
tidyr::crossing(df, data.frame(id = 1:n))

# dplyr version of the row-index method above
slice(df, rep(1:n(), n)) %>% mutate(id = rep(1:n, each = nrow(df)))

灵感源于我的一个古老问题How can I repeat a data frame?。基本上是相同的问题,但没有id列的要求。