1

我有以下格式的半长数据框:

| Id | Alt | Choice | Var1 | Var2 |
|----+-----+--------+------+------|
|  1 | a   | TRUE   | 58.2 |    4 |
|  1 | b   | FALSE  | 71.6 |    5 |
|  2 | a   | FALSE  | 14.8 |    2 |
|  2 | b   | TRUE   | 82.1 |    5 |

...我想重塑为以下格式:

| Id | Choice.a | Choice.b | Var1.a | Var1.b | Var2.a | Var2.b |
|----+----------+----------+--------+--------+--------+--------|
| 1  | TRUE     | FALSE    | 58.2   | 71.6   | 4      | 5      |
| 2  | FALSE    | TRUE     | 14.8   | 82.1   | 2      | 5      |

我一直在想,我应该能够做类似的事情:

library(reshape2)
dcast(df, ... ~ Alt)

但这并不完全正确。

4

2 回答 2

7

这不是使用“plyr”,而是使用基本功能reshape

 dat <- read.table(text=" Id | Alt | Choice | Var1 | Var2 
  1 |a| TRUE   | 58.2 |    4 
  1 |b| FALSE  | 71.6 |    5 
  2 |a| FALSE  | 14.8 |    2
  2 |b| TRUE   | 82.1 |    5
 ", sep="|", header=TRUE)
 reshape(dat, direction="wide", idvar="Id", timevar="Alt")
#-----------------
  Id Choice.a Var1.a Var2.a Choice.b Var1.b Var2.b
1  1  TRUE      58.2      4  FALSE     71.6      5
3  2  FALSE     14.8      2  TRUE      82.1      5

如果您需要显示的精确顺序,使用“[”就足够了。想象一下,我们将 reshape() 的结果分配给“wdat”:

wdat[c(1,2,5,3,6,4,7)]
#===============
  Id Choice.a Choice.b Var1.a Var1.b Var2.a Var2.b
1  1  TRUE     FALSE     58.2   71.6      4      5
3  2  FALSE    TRUE      14.8   82.1      2      5
于 2012-09-11T00:11:05.403 回答
1

您要做的是更改value每次使用的列。您将无法在一次调用中执行此操作dcast

这是一个使用lapplyandReduce合并结果的示例

library(plyr) #for . and rename
df <- data.frame(Id = rep(1:2,each=2), Alt = c('a','b'),Choice = c(T,F,F,T), Var1= c(58.2,71.6,14.8,82.1),Var2 =c(4,5,2,5))  

by_cols <- c('Choice','Var1','Var2')
df_list <- lapply(by_cols, function(value, data, formula = Id~Alt) {
     new <- dcast(data, formula, value.var = value )
     # rename not just a a
     unique_alt <- unique(data[[as.character(formula)[3]]])
     rename(new, setNames(paste(value, unique_alt, sep='.'), unique_alt))},
       data = df)

Reduce(function(x,y){merge(x,y,by='Id',all=T)}, df_list)

##   Id Choice.a Choice.b Var1.a Var1.b Var2.a Var2.b
## 1  1     TRUE    FALSE   58.2   71.6      4      5
## 2  2    FALSE     TRUE   14.8   82.1      2      5

矢量化 dcast

您可以使用Vectorize创建矢量化版本dcast

dcast.vector <- Vectorize(dcast, vectorize.args = 'value.var', SIMPLIFY = F)

df_list <- dcast.vector(df, Id ~ Alt, value.var = by_cols)

您仍然需要wide从 just 重命名列ab

 old_names <- c('a','b')
 new_names <- setNames(lapply(by_cols, paste, old_names, sep = '.'), by_cols)
 df_list <- mapply(rename, df_list, replace = new_names, SIMPLIFY = F)

你还需要Reduce一步

 Reduce(function(x,y){merge(x,y,by='Id',all=T)}, df_list)

基础 R 重塑是一个更直接的解决方案。

于 2012-09-11T00:13:13.937 回答