reshape2 dcast 非数字参数到二元运算符

reshape2 dcast non-numeric argument to binary operator

我正在尝试使用 reshape2 中的 dcast 将数据帧从长数据帧转换为宽数据帧。

我创建了一个这样的数据框:

> 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)

并得到,

> 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

然后,用dcast

> library(reshape2)
> dcast(df, Person + Object, variable.var="Value", fun.aggregate=length)
Error in Person + Object : non-numeric argument to binary operator

为什么 dcast 仍然需要 Person 和 Object 列的数字参数?

我正在尝试获取此输出:

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

* 编辑 * @neilfws 找到了解决方案:

dcast(df, Person ~ . + Object, variable.var="Value")

但是,当从制表符分隔文件导入数据框时:

df = read.table("Person_Object.tab", header=T, sep="\t")

相同的 dcast 命令returns:

Error in eval(expr, envir, enclos) : object 'Person' not found

显示如何填充空单元格。

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
> 

我们可以使用tidyverse

library(tidyr)
df %>% 
    spread(Object, 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