R从宽到长用列名重塑
R wide to long reshape with column names
我有这种格式的数据
A1 A2 B1 B2 C1 C2
10 5 11 5 21 10
我想将其转换为:
1 2
A 10 5
B 11 5
C 21 10
如何在 R 中实现?
我们可以 gather
变成 'long' 格式,然后 separate
'key' 列在数字部分之前分成两列, spread
它到 'wide' 并将 'key1' 列更改为行名称
library(tidyverse)
gather(df1) %>%
separate(key, into = c('key1', 'key2'), sep="(?=\d)") %>%
spread(key2, value) %>%
column_to_rownames('key1')
# 1 2
#A 10 5
#B 11 5
#C 21 10
数据
df1 <- structure(list(A1 = 10L, A2 = 5L, B1 = 11L, B2 = 5L, C1 = 21L,
C2 = 10L), class = "data.frame", row.names = c(NA, -1L))
一个data.table
解决方案:
library(data.table)
library(magrittr)
melt(df1, measure.vars = names(df1)) %>%
.[, c("l", "n") := tstrsplit(variable, "")] %>%
dcast(l ~ n)
l 1 2
1: A 10 5
2: B 11 5
3: C 21 10
问题的标签是 r、reshape 和 reshape2,因此我们展示了使用其中每一个的解决方案。
1) xtabs 基本的 R 解决方案如下。
let <- gsub("\d", "", names(DF))
num <- gsub("\D", "", names(DF))
tab <- xtabs(unlist(DF) ~ let + num)
给予:
> tab
num
let 1 2
A 10 5
B 11 5
C 21 10
或数据框:
cbind(let = rownames(tab), as.data.frame.matrix(tab))
给予:
let 1 2
A A 10 5
B B 11 5
C C 21 10
2) reshape 另一个基本的 R 解决方案如下。 let
和num
来自上面。
varying <- split(names(DF), num)
reshape(DF, dir = "long", varying = varying, v.names = names(varying),
times = unique(let), timevar = "let")[-4]
给予:
let 1 2
1.A A 10 5
1.B B 11 5
1.C C 21 10
3) reshape2 使用上面的 let
和 num
:
library(reshape2)
dcast(let ~ num, data = data.frame(value = unlist(DF)), value.var = "value")
给予:
let 1 2
1 A 10 5
2 B 11 5
3 C 21 10
备注
可重现形式的输入:
Lines <- "
A1 A2 B1 B2 C1 C2
10 5 11 5 21 10"
DF <- read.table(text = Lines, header = TRUE)
我有这种格式的数据
A1 A2 B1 B2 C1 C2
10 5 11 5 21 10
我想将其转换为:
1 2
A 10 5
B 11 5
C 21 10
如何在 R 中实现?
我们可以 gather
变成 'long' 格式,然后 separate
'key' 列在数字部分之前分成两列, spread
它到 'wide' 并将 'key1' 列更改为行名称
library(tidyverse)
gather(df1) %>%
separate(key, into = c('key1', 'key2'), sep="(?=\d)") %>%
spread(key2, value) %>%
column_to_rownames('key1')
# 1 2
#A 10 5
#B 11 5
#C 21 10
数据
df1 <- structure(list(A1 = 10L, A2 = 5L, B1 = 11L, B2 = 5L, C1 = 21L,
C2 = 10L), class = "data.frame", row.names = c(NA, -1L))
一个data.table
解决方案:
library(data.table)
library(magrittr)
melt(df1, measure.vars = names(df1)) %>%
.[, c("l", "n") := tstrsplit(variable, "")] %>%
dcast(l ~ n)
l 1 2
1: A 10 5
2: B 11 5
3: C 21 10
问题的标签是 r、reshape 和 reshape2,因此我们展示了使用其中每一个的解决方案。
1) xtabs 基本的 R 解决方案如下。
let <- gsub("\d", "", names(DF))
num <- gsub("\D", "", names(DF))
tab <- xtabs(unlist(DF) ~ let + num)
给予:
> tab
num
let 1 2
A 10 5
B 11 5
C 21 10
或数据框:
cbind(let = rownames(tab), as.data.frame.matrix(tab))
给予:
let 1 2
A A 10 5
B B 11 5
C C 21 10
2) reshape 另一个基本的 R 解决方案如下。 let
和num
来自上面。
varying <- split(names(DF), num)
reshape(DF, dir = "long", varying = varying, v.names = names(varying),
times = unique(let), timevar = "let")[-4]
给予:
let 1 2
1.A A 10 5
1.B B 11 5
1.C C 21 10
3) reshape2 使用上面的 let
和 num
:
library(reshape2)
dcast(let ~ num, data = data.frame(value = unlist(DF)), value.var = "value")
给予:
let 1 2
1 A 10 5
2 B 11 5
3 C 21 10
备注
可重现形式的输入:
Lines <- "
A1 A2 B1 B2 C1 C2
10 5 11 5 21 10"
DF <- read.table(text = Lines, header = TRUE)