2013-07-14 55 views
0

我有这样的数据帧:重塑acast()删除缺失值

df <- data.frame(subject = c(rep("one", 20), c(rep("two", 20))), 
       score1 = sample(1:3, 40, replace=T), 
       score2 = sample(1:6, 40, replace=T), 
       score3 = sample(1:3, 40, replace=T), 
       score4 = sample(1:4, 40, replace=T)) 

    subject score1 score2 score3 score4 
1  one  2  4  2  2 
2  one  3  3  1  2 
3  one  1  2  1  3 
4  one  3  4  1  2 
5  one  1  2  2  3 
6  one  1  5  2  4 
7  one  2  5  3  2 
8  one  1  5  1  3 
9  one  3  5  2  2 
10  one  2  3  3  4 
11  one  3  2  1  3 
12  one  2  5  2  1 
13  one  2  4  1  4 
14  one  2  2  1  3 
15  one  1  3  1  4 
16  one  1  6  1  3 
17  one  3  4  2  2 
18  one  3  2  1  3 
19  one  2  5  3  1 
20  one  3  6  2  1 
21  two  1  6  3  4 
22  two  1  2  1  2 
23  two  3  2  1  2 
24  two  1  2  2  1 
25  two  2  3  1  3 
26  two  1  5  3  3 
27  two  2  4  1  4 
28  two  2  6  2  4 
29  two  1  6  2  2 
30  two  1  5  1  4 
31  two  2  1  2  4 
32  two  3  6  1  1 
33  two  1  1  3  1 
34  two  2  4  2  3 
35  two  2  1  3  2 
36  two  2  3  1  3 
37  two  1  2  3  4 
38  two  3  5  2  2 
39  two  2  1  3  4 
40  two  2  1  1  3 

注意,分数有不同范围的值。从1-3分数1个范围,从-6得分2,从1-3评分3,得分4 1-4

我试图重塑像这样的数据:

library(reshape2) 
dfMelt <- melt(df, id.vars="subject") 

acast(dfMelt, subject ~ value ~ variable) 

Aggregation function missing: defaulting to length 
, , score1 

    1 2 3 4 5 6 
one 6 7 7 0 0 0 
two 8 9 3 0 0 0 

, , score2 

    1 2 3 4 5 6 
one 0 5 3 4 6 2 
two 5 4 2 2 3 4 

, , score3 

    1 2 3 4 5 6 
one 10 7 3 0 0 0 
two 8 6 6 0 0 0 

, , score4 

    1 2 3 4 5 6 
one 3 6 7 4 0 0 
two 3 5 5 7 0 0 

注意如果输出数组缺失,则输出数组的分数为“0”。有没有办法阻止acast输出的这些缺失分数?

+0

'acast'的返回值是一个数组,所以唯一的选择就是'NA',你以后可以转换为0〜'NA'。 – Roland

+1

@Roland,你可以使用'fill'参数来'acast':'acast(dfMelt,subject_value_variable,fill = NA_integer_)'来直接获得NA。 – Arun

+0

@luciano,当你说“阻止他们输出”,你的意思是输出到屏幕,还是你想他们不被列入每个阵列? –

回答

1

在这种情况下,您可能会更好地坚持基本R的table功能。我不确定你可以有一个不规则的array像你正在寻找。

例如:

> lapply(df[-1], function(x) table(df[[1]], x)) 
$score1 
    x 
     1 2 3 
    one 9 6 5 
    two 11 4 5 

$score2 
    x 
     1 2 3 4 5 6 
    one 2 5 4 3 3 3 
    two 4 2 2 3 4 5 

$score3 
    x 
     1 2 3 
    one 9 5 6 
    two 4 11 5 

$score4 
    x 
     1 2 3 4 
    one 4 4 8 4 
    two 2 6 5 7 

或者,使用您的“长”数据:

with(dfMelt, by(dfMelt, variable, 
       FUN = function(x) table(x[["subject"]], x[["value"]]))) 
1

由于每个“分数”的子集都将有不同的形状,你将不能够保留数组结构。一种选择是使用双暗阵列或data.frames列表。例如:

# your original acast call 
res <- acast(dfMelt, subject ~ value ~ variable) 

# remove any columns that are all zero 
apply(res, 3, function(x) x[, apply(x, 2, sum)!=0]) 

其中给出:

$score1 
    1 2 3 
one 7 8 5 
two 6 8 6 

$score2 
    1 2 3 4 5 6 
one 4 2 6 4 1 3 
two 2 5 3 4 3 3 

$score3 
    1 2 3 
one 5 10 5 
two 5 11 4 

$score4 
    1 2 3 4 
one 5 4 4 7 
two 4 6 6 4