我正在尝试转换以下格式:
mydata <- data.frame(movie = c("Titanic", "Departed"),
actor1 = c("Leo", "Jack"),
actor2 = c("Kate", "Leo")))
movie actor1 actor2
1 Titanic Leo Kate
2 Departed Jack Leo
到二元响应变量:
movie Leo Kate Jack
1 Titanic 1 1 0
2 Departed 1 0 1
我尝试了中描述的解决方案 Convert row data to binary columns 但我可以让它适用于两个变量,而不是三个变量。
如果有一个干净的方法,我真的很感激。
答案 0 :(得分:15)
多少香料太多了?以下是tidyr
的解决方案:
library(dplyr)
library(tidyr)
mydata %>%
gather(actor,name,starts_with("actor")) %>%
mutate(present = 1) %>%
select(-actor) %>%
spread(name,present,fill = 0)
movie Jack Kate Leo
1 Departed 1 0 1
2 Titanic 0 1 1
答案 1 :(得分:7)
重塑data.frame
的一种方法是使用reshape2
包,使用melt
和dcast
。例如:
library(reshape2)
long.mydata <- melt(mydata, id.vars = "movie")
wide.mydata <- dcast(long.mydata, movie ~ value, function(x) 1, fill = 0)
请注意fun.aggregate
中的fill
和dcast
参数,这些参数控制在施法后填充内部的内容。
答案 2 :(得分:4)
既然他们说多样性是生活的调味品,这里是使用table
的基础R的方法:
table(cbind(mydata[1],
actor = unlist(mydata[-1], use.names=FALSE)))
# actor
# movie Jack Leo Kate
# Departed 1 1 0
# Titanic 0 1 1
以上输出是matrix
类的table
。要获得data.frame
,请使用as.data.frame.matrix
。
as.data.frame.matrix(table(
cbind(mydata[1], actor = unlist(mydata[-1], use.names=FALSE))))
# Jack Leo Kate
# Departed 1 1 0
# Titanic 0 1 1
答案 3 :(得分:1)
reshape2
- 包还有recast
- 函数。
代码:
library(reshape2)
recast(mydata, id.var = 'movie', movie ~ value, fun.aggregate = length)
结果:
movie Jack Kate Leo
1 Departed 1 0 1
2 Titanic 0 1 1
答案 4 :(得分:1)
更新的基于tidyr
的选项是转换为长形,使用complete
填充缺少的电影和演员组合,然后将逻辑is.na
测试转换为一个数值。然后重新变宽。
library(tidyr)
mydata %>%
pivot_longer(starts_with("actor"), names_to = "acted") %>%
complete(movie, value) %>%
dplyr::mutate(acted = as.numeric(!is.na(acted))) %>%
pivot_wider(names_from = value, values_from = acted)
#> # A tibble: 2 x 4
#> movie Jack Leo Kate
#> <fct> <dbl> <dbl> <dbl>
#> 1 Departed 1 1 0
#> 2 Titanic 0 1 1