展平数据框并将行移至列

时间:2018-03-08 22:31:32

标签: r dataframe tidyverse

我有一个像这样的数据框:

df <- data.frame(
  id = c(1, 1, 2, 2), 
  V1 = c(1:4), 
  V2 = c(5:8), 
  V3 = c(9:12))

打印到控制台看起来像这样:

#   id V1 V2 V3
# 1  1  1  5  9
# 2  1  2  6 10
# 3  2  3  7 11
# 4  2  4  8 12

现在,我想将其转换为这种形状:

#   id V1 V2 V3 V4 V5 V6
# 1  1  1  5  9  2  6 10
# 2  2  3  7 11  4  8 12

如何使用基础R或tidyverse执行此操作?

3 个答案:

答案 0 :(得分:2)

你可以用例如使用by

df2 <- do.call(rbind,
  by(df, df$id, function(x) c(x[1, "id"], as.vector(t(x[names(x) != "id"]))))
  )

colnames(df2) <- c("id", paste0("V", seq(ncol(df2)-1)))

  id V1 V2 V3 V4 V5 V6
1  1  1  5  9  2  6 10
2  2  3  7 11  4  8 12

答案 1 :(得分:2)

可能的tidyverse解决方案

wide <- df %>%
  group_by(id) %>%
  mutate(obs = row_number()) %>%
  gather(var, val, V1:V3) %>%
  unite(comb, obs, var) %>%
  spread(comb, val)

colnames(wide)[-1] <- paste("V", seq(1,ncol(wide) -1), sep = "")

# A tibble: 2 x 7
# Groups:   id [2]
#     id    V1    V2    V3    V4    V5    V6
#1     1     1     5     9     2     6    10
#2     2     3     7    11     4     8    12

答案 2 :(得分:1)

基地R:

lists <- Map(function(x) data.frame(c(x[1,], x[2,-1])), split(df, df$id))
df2   <- do.call(rbind, lists)

要更改列名称:

colnames(df2) <- c("id", paste0("V", seq_along(df2[-1])))

结果:

# > df2
#   id V1 V2 V3 V4 V5 V6
# 1  1  1  5  9  2  6 10
# 2  2  3  7 11  4  8 12