如何在R中进行简单的转置/转轴

时间:2015-02-11 20:28:20

标签: r reshape

我只想获取一个包含两列的数据框,一列带有分组变量,第二列带有值,然后对其进行转换,使分组变量成为具有适当值的列。一个非常简单的问题,但搜索了大约一个小时后,我找不到一个好的答案。这是一个玩具示例:

var <- c("Var1", "Var1", "Var2", "Var2")
value <- c(1, 2, 3, 4)

df <- data.frame(var, value)

df.one <- df[df$var == "Var1", ]
df.two <- df[df$var == "Var2", ]

desired.df <- data.frame(df.one[2], df.two[2])
colnames(desired.df) <- c("Var1", "Var2")

desired.df

随着更多的变量和值,这段代码可能变得非常笨重。有谁能建议更好的方法?任何建议将不胜感激!

2 个答案:

答案 0 :(得分:5)

数据:

df <- structure(list(var = structure(c(1L, 1L, 2L, 2L), 
.Label = c("Var1", "Var2"), class = "factor"), 
 value = c(1, 2, 3, 4)), .Names = c("var", "value"), 
 class = "data.frame", row.names = c(NA, -4L))

var中引入一个标识观察结果的新变量看起来很有用(我在下面称之为case);如果你愿意,你可以在重塑它之后将其删除。

使用reshape2 / plyr

library("plyr")
library("reshape2")
## add 'case' identifier
df <- ddply(df,"var",mutate,case=1:length(var))
## dcast() to reshape; then drop identifier
dcast(df,case~var)[,-1]

使用tidyr(相同策略):

library("tidyr")
library("dplyr")
df %>% group_by(var) %>%
    mutate(case=seq(n())) %>%
        spread(var,value) %>%
            select(-case)

这可能也可以用基础R中的reshape()完成,但我从来没有弄明白......

答案 1 :(得分:4)

Base R解决方案:

data.frame(split(df$value,df$var))
#  Var1 Var2
#1    1    3
#2    2    4

这个解决方案意味着所有的“Varn”&#39;子集的长度相等。 更一般的解决方案是:

z <- split(df$value,df$var)
max.length <- max(sapply(z,length))
data.frame(lapply(z,`length<-`,max.length))

将NA附加到较短的列表,以确保所有列表具有相同的长度。