r-我可以使用pivot_langer来生成一系列二分变量吗



我的数据集大致如下。有没有一种方法可以使用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)
>2000年><1> td style="text align=center;">0
vaar1var2var31985style="text align=center;">1990年1995年
红色0向上00000

使用来自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
  1. 很明显,id_colsvar1:var3,例如,我们不想改变它们。因此,我们的重点是election列。

  2. 同样明显的是,您希望election是列名,因此names_from = election也是列名,但当我们进行透视时,我们也希望对election进行处理。

  3. 查看示例数据帧,其中var1 == "red", var2 == 1, var3 == "down"在选举中的值不是由var1:var3唯一标识的。因此,对于行var1 == "red", var2 == 1, var3 == "down"和列`1965`,在这种情况下我们有两个值:c(1965, 1965)pivot_wider不确定如何处理这些值(默认情况下,它将它们存储为list对象(。

  4. 因此,我们提供了关于在这种情况下要做什么的说明,pivot_wider应用我们传递给values_fn的函数。在该示例中,这将解析为as.integer(length(c(1965,1965)) > 0),并且在这种情况下输出变为1。即使在它被唯一识别的地方,这个功能仍然可以工作:

as.integer(length(c(1980)) > 0)
[1] 1

因为我们只是测试是否有值,如果有.则返回1

  1. 最后,并非每个election列都有var1:var3的值。对于本例,没有1985。默认情况下,pivot_wider将使用NA填充该值。我们提供了用带有values_fill参数的整数0L填充它的指令。试着在这个参数被注释掉的情况下运行它,它应该是清晰的

最新更新