I am trying to convert a data frame from long to wide using dcast
from reshape2
.
I create a data frame like this:
> Person=c("A","A","A","A","B","B","C","C","C","C")
> Object=c("car", "watch", "bike", "phone","car","skateboard","car","bike","motorcycle")
> Value=c("1","1","1","1","1","1","1","1","1","1")
> df=data.frame(Person, Object, Value)
and get,
> df
Person Object Value
1 A car 1
2 A watch 1
3 A bike 1
4 A phone 1
5 B car 1
6 B skateboard 1
7 C car 1
8 C bike 1
9 C motorcycle 1
10 C TV 1
Then, with dcast
> library(reshape2)
> dcast(df, Person + Object, variable.var="Value", fun.aggregate=length)
Error in Person + Object : non-numeric argument to binary operator
Why dcast would need numeric argument for Person and Object column anyway?
I am trying to get this output:
Person car watch bike phone skateboard motorcycle TV
A 1 1 1 1 0 0 0
B 1 0 0 0 1 0 0
C 1 0 1 0 0 1 1
* EDIT * @neilfws found a solution:
dcast(df, Person ~ . + Object, variable.var="Value")
However, when the data frame is imported from a tab-delimited file:
df = read.table("Person_Object.tab", header=T, sep="\t")
the same dcast command returns:
Error in eval(expr, envir, enclos) : object 'Person' not found
Showing how to fill empty cells.
Person=c("A","A","A","A","B","B","C","C","C","C")
Object=c("car", "watch", "bike", "phone","car","skateboard","car","bike","motorcycle", "TV")
Value=c("1","1","1","1","1","1","1","1","1","1")
# note the extra parameter StringsAsFactors - needed so that "0" can be used
df=data.frame(Person, Object, Value, stringsAsFactors = FALSE)
library(reshape2)
dcast(df, Person ~ Object, value.var="Value", fill = "0")
# Person bike car motorcycle phone skateboard TV watch
# 1 A 1 1 0 1 0 0 1
# 2 B 0 1 0 0 1 0 0
# 3 C 1 1 1 0 0 1 0
>