下面是一个示例。如何将具有列df
的数据帧names
转换为下面df.transformed
的形式?
> df <- data.frame("names" = c("y1", "y2"), "x1" = 1:2, "x2" = 4:5)
> df
names x1 x2
1 y1 1 4
2 y2 2 5
> df.transformed <- data.frame("y1x1" = 1, "y1x2" =4, "y2x1" = 2, "y2x2" = 5)
> df.transformed
y1x1 y1x2 y2x1 y2x2
1 1 4 2 5
答案 0 :(得分:4)
代码
require(data.table); setDT(df)
dt = melt(df, id.vars = 'names')[, col := paste0(variable, names)]
out = dt$value; names(out) = dt$col
结果
> data.frame(t(out))
x1y1 x1y2 x2y1 x2y2
1 2 4 5
答案 1 :(得分:3)
您可以在基本R中实现这一点。它适用于任何数据帧大小。这个想法是将Reduce
与outer
结合起来以构建数据框列名。
df <- data.frame("names" = c("y1", "y2"), "x1" = 1:2, "x2" = 4:5)
df_names <- outer(df[,1], names(df[,-1]), paste0)
df.transformed <- as.data.frame(matrix(,ncol = nrow(df)*ncol(df[,-1]), nrow = 0))
names(df.transformed) <- Reduce(`c`,t(df_names))
df.transformed[1,] <- Reduce(`c`,t(df[-1]))
输出
# y1x1 y1x2 y2x1 y2x2
# 1 4 2 5
答案 2 :(得分:1)
您可以使用新的tidyr::pivot_wider
在同一行中执行此操作。为值设置多列意味着名称将被粘贴在一起进行赋值。
library(tidyr)
pivot_wider(df, names_from = names, values_from = c(x1, x2), names_sep = "")
#> # A tibble: 1 x 4
#> x1y1 x1y2 x2y1 x2y2
#> <int> <int> <int> <int>
#> 1 1 2 4 5
但是,列名(“ x1”,“ x2”)排在最前面。如果需要交换名称的“ x”和“ y”部分,则可以用dplyr::rename_all
进行正则表达式替换。
df %>%
pivot_wider(names_from = names, values_from = c(x1, x2), names_sep = "") %>%
dplyr::rename_all(gsub, pattern = "(x\\d+)(y\\d+)", replacement = "\\2\\1")
#> # A tibble: 1 x 4
#> y1x1 y2x1 y1x2 y2x2
#> <int> <int> <int> <int>
#> 1 1 2 4 5