【问题标题】:Can I use pivot_longer to make a series of dichotomous variable?我可以使用 pivot_longer 来制作一系列二分变量吗?
【发布时间】:2021-05-26 18:37:16
【问题描述】:

我的数据集大致如下所示。有没有办法使用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 1965 1970 1975 1980 1985 1990 1995 2000
red 0 up 1 0 0 0 0 0 0 0 0 0 0 0

【问题讨论】:

    标签: r tidyverse


    【解决方案1】:

    使用来自data.tableR 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
    

    【讨论】:

      【解决方案2】:
      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 版本为 \(x) 替换为 function(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)) &gt; 0),并且在这种情况下输出变为1。即使它是唯一标识的,此功能仍然有效:

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

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

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

      【讨论】:

      • 如果您想改进输出列的顺序,可以使用names_sort 参数(names_sort = TRUE)。 :)
      • 而如果R版本为4.1以上,可以将%&gt;%替换为|&gt;;-)
      • @tpetzoldt 感谢您的评论——尽管%&gt;% 管道是通过库tidyr 导入的。
      • 当然 ;-) 这只是出于好奇,因为我想知道 magritter %&gt;% 将来会发生什么,因为 R 现在已经内置了原生管道。但这肯定是这里的主题。
      • 我自己的计划是坚持使用 %>% ;变化太大!!!!
      猜你喜欢
      • 1970-01-01
      • 2012-11-01
      • 2011-10-08
      • 2013-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多