我的数据集大致如下。有没有一种方法可以使用pivot_longer()
将列变量转换为一系列二分变量,1表示行有该值,0表示没有?
这是不对的,但这是我的尝试。期望的输出在末尾。
library(tidyverse)
election<-sample(seq(1965,2000, by=5),replace=T, size=100)
var1<-sample(c('red', 'blue'), replace=T, size=100)
var2<-sample(c(0,1), replace=T, size=100)
var3<-sample(c('up', 'down'), replace=T, size=100)
df<-data.frame(election, var1, var2, var3)
df %>%
pivot_longer(names_from=election, values_from=election)
vaar1 | var2 | var3 | >1985style="text align=center;">1990年 | 1995年 | 2000年>|||
---|---|---|---|---|---|---|---|
红色 | 0 | 向上 | <1> td style="text align=center;">00 | 0 | 0 | 0 | 0 |
使用来自data.table
(R 4.1.0
(的dcast
library(data.table)
dcast(setDT(df), ... ~ election, value.var = 'election', (x) +(length(x) > 0))
-输出
var1 var2 var3 1965 1970 1975 1980 1985 1990 1995 2000
1: blue 0 down 1 1 1 1 0 1 1 1
2: blue 0 up 0 1 1 1 1 1 0 1
3: blue 1 down 1 1 0 0 1 1 1 1
4: blue 1 up 1 1 0 1 0 1 0 1
5: red 0 down 1 1 1 1 1 1 0 1
6: red 0 up 1 1 1 0 0 1 1 1
7: red 1 down 1 1 1 1 1 0 1 1
8: red 1 up 1 1 1 1 1 1 1 1
library(tidyr)
df %>%
pivot_wider(id_cols = var1:var3,
names_from = election,
values_from = election,
values_fn = (x) as.integer(length(x) > 0),
values_fill = 0L,
names_sort = T)
如果您的R
版本是<4.1.0然后用function(x)
替换(x)
。
输出
var1 var2 var3 `1965` `1970` `1975` `1980` `1985` `1990` `1995` `2000`
<chr> <dbl> <chr> <int> <int> <int> <int> <int> <int> <int> <int>
1 red 1 down 1 1 1 1 0 1 0 1
2 red 0 down 1 1 1 1 1 1 1 1
3 red 1 up 1 1 0 1 1 0 1 1
4 blue 0 down 1 1 1 1 1 1 1 1
5 blue 1 down 0 1 1 1 1 0 1 0
6 blue 1 up 1 0 0 0 1 1 1 1
7 blue 0 up 1 1 0 1 1 0 0 1
8 red 0 up 0 0 1 0 0 1 0 1
它的工作原理
为了帮助理解这是如何工作的,请关注将成为枢轴数据帧中一行的内容:
df %>% filter(var1 == "red", var2 == 1, var3 == "down") %>% arrange(election)
election var1 var2 var3
1 1965 red 1 down
2 1965 red 1 down
3 1970 red 1 down
4 1975 red 1 down
5 1980 red 1 down
6 1990 red 1 down
7 1990 red 1 down
8 2000 red 1 down
9 2000 red 1 down
10 2000 red 1 down
11 2000 red 1 down
很明显,
id_cols
是var1:var3
,例如,我们不想改变它们。因此,我们的重点是election
列。同样明显的是,您希望
election
是列名,因此names_from = election
也是列名,但当我们进行透视时,我们也希望对election
的值进行处理。查看示例数据帧,其中
var1 == "red", var2 == 1, var3 == "down"
在选举中的值不是由var1:var3
唯一标识的。因此,对于行var1 == "red", var2 == 1, var3 == "down"
和列`1965`
,在这种情况下我们有两个值:c(1965, 1965)
和pivot_wider
不确定如何处理这些值(默认情况下,它将它们存储为list
对象(。因此,我们提供了关于在这种情况下要做什么的说明,
pivot_wider
应用我们传递给values_fn
的函数。在该示例中,这将解析为as.integer(length(c(1965,1965)) > 0)
,并且在这种情况下输出变为1
。即使在它被唯一识别的地方,这个功能仍然可以工作:
as.integer(length(c(1980)) > 0)
[1] 1
因为我们只是测试是否有值,如果有.则返回1
- 最后,并非每个
election
列都有var1:var3
的值。对于本例,没有1985
。默认情况下,pivot_wider
将使用NA
填充该值。我们提供了用带有values_fill
参数的整数0L
填充它的指令。试着在这个参数被注释掉的情况下运行它,它应该是清晰的