【问题标题】:R - compare multiple columns and create new columns indicating matchesR - 比较多列并创建指示匹配的新列
【发布时间】:2014-12-27 14:00:19
【问题描述】:

我想知道如何将多列与单列中的值进行比较,然后使用这些匹配项来创建差异表。我有一个政策结果的政治数据集,以及某些组织是否支持或反对这些结果,按年份划分。这是一些模拟数据:

结果 0 表示法律从未发生,结果 1 表示发生了。 对于组织而言,负数表示他们反对该法律,正数表示他们支持该法律:

set.seed(123)
Data <- data.frame(
  year = sample(1998:2004, 200, replace = TRUE),
  outcome = sample(0:1, 200, replace = TRUE),
  union = sample(-1:1, 200, replace = TRUE),
  chamber = sample(-1:1, 200, replace = TRUE),
  pharma = sample(-1:1, 200, replace = TRUE),
  gun = sample(-1:1, 200, replace = TRUE),
  dem = sample(-1:1, 200, replace = TRUE),
  repub = sample(-1:1, 200, replace = TRUE)
)

我想知道一个组织每年有多少次得到工会的支持或反对。

我想它会是这样的表格,其中匹配等于 1,否则为 -1(数据中也有许多 NA,组织不采取任何立场):

DATA$contra <- ifelse(DATA$union == page.bin$chamber, 1, -1)

在数据集中,连续列中大约有 50 个组织。为每场比赛创建 50 个新列似乎并不实用。即使这是最好的方法,我也不知道如何应用该函数来创建 50 个新列。

最后,我想创建一个热图或一种方法来可视化哪些组织与联合列匹配。但是,首先,我认为,我需要某种数据表。

感谢您的帮助!

【问题讨论】:

  • 根据实际数据的样子,您可以先将 df 重塑为长格式,这样您就有一个变量“组织”,然后您可以汇总数据,按年份和组织分组并使用例如如果是。
  • 建议您将问题编辑为 a) 使用 set.seed() 使其可重现,b) 使示例名称保持一致。

标签: r


【解决方案1】:

当您说“我想知道一个组织每年有多少次得到工会的支持或反对”。那么我假设您想要协议的净数量,即发生 1/1 投票或 -1/-1 投票配对,并且您希望从中减去不同意的数量,而不关心数量其中一张票是 0 次。

在运行您的代码之前,我使用了 set.seed(123) 以便可以重现:

> head(Data)
  year outcome union chamber pharma gun dem repub
1 2000       0     1      -1      0  -1   1    -1
2 2003       1    -1       1      0   0   1    -1
3 2000       1     1      -1     -1  -1   0    -1
4 2004       1     0      -1     -1   1   1     0
5 2004       0     0      -1     -1   1   0    -1
6 1998       1     0       1      1   0   1     1

> head( Data[-(1:3)] * Data[[3]])
  chamber pharma gun dem repub
1      -1      0  -1   1    -1
2      -1      0   0  -1     1
3      -1     -1  -1   0    -1
4       0      0   0   0     0
5       0      0   0   0     0
6       0      0   0   0     0

这使得 1/1 和 -1/-1 配对全部为 ==1 和 -1/1 和 1/-1 配对 ==-1 和其他 ==0。现在可以按年份汇总:

> head( aggregate( Data[-(1:3)] * Data[[3]], Data[1], sum) )
  year chamber pharma gun dem repub
1 1998       0     -2   1   2     6
2 1999       0      0   2   4     3
3 2000      -3      2  -3  -4   -11
4 2001       2      3   2   9     1
5 2002       0     -1   7   9     1
6 2003       0     -2 -11   5    -2

如果您只想要协议的总和,那将是:

>  aggregate( Data[-(1:3)] * Data[[3]], Data[1], function(x) {sum(x==1)} )
  year chamber pharma gun dem repub
1 1998       5      4   5   7     9
2 1999       8      7   7   9     9
3 2000       5      8   5   3     3
4 2001       7      9   7  11     4
5 2002       7      6  11  12     9
6 2003       7      5   1   8     5
7 2004       4      4   9   2     4

【讨论】:

    【解决方案2】:

    使用dplyr

    library(dplyr)
    
    Data %>% 
      select(-outcome) %>%
      group_by(year, union) %>% 
      mutate_each(funs(union * .)) %>%
      group_by(year) %>%
      summarise_each(funs(sum(. == 1)), -union) 
    

    你得到:

    Source: local data frame [7 x 6]
    
      year chamber pharma gun dem repub
    1 1998       5      4   5   7     9
    2 1999       8      7   7   9     9
    3 2000       5      8   5   3     3
    4 2001       7      9   7  11     4
    5 2002       7      6  11  12     9
    6 2003       7      5   1   8     5
    7 2004       4      4   9   2     4
    

    使用来自tidyrgather() 获取高格式数据和ggvis 热图

    library(dplyr)
    library(tidyr)
    library(ggvis)
    
    Data %>% 
      select(-outcome) %>%
      group_by(year, union) %>% 
      mutate_each(funs(union * .)) %>%
      group_by(year) %>%
      summarise_each(funs(sum(. == 1)), -union) %>%
      gather(org, value, -year) %>%
      mutate(org = as.factor(org), year = as.factor(year)) %>%
      ggvis(~year, ~org, fill=~value) %>%
      layer_rects(width = band(), height = band()) %>%
      layer_text(
        x = prop("x", ~year, scale = "xcenter"),
        y = prop("y", ~org, scale = "ycenter"),
        text:=~value, fontSize := 14, fill:="white", 
        baseline:="middle", align:="center") %>%
      scale_nominal("x", padding = 0, points = FALSE) %>%
      scale_nominal("y", padding = 0, points = FALSE) %>% 
      scale_nominal("x", name = "xcenter", padding = 1, points = TRUE) %>%
      scale_nominal("y", name = "ycenter", padding = 1, points = TRUE) %>%
      hide_legend("fill")
    

    【讨论】:

      【解决方案3】:

      也许以下有帮助。首先,您创建一个新的数据框,其中包含每个组织和每一行的支持是否匹配联合:

      match.union <- data.frame(year=Data$year,
                         lapply(Data[,4:ncol(Data)],function(col) col==Data$union))
      

      重要的是要为下一步添加带有年份的列,即总结每年与工会的协议数量:

      aggregate(.~year,match.union,sum)
      

      我从中得到的输出是

        year chamber pharma gun dem repub
      1 1998      11      9  10   9     7
      2 1999      10      8  16   9    14
      3 2000       8      9   8   7    12
      4 2001       7      9  10   9    13
      5 2002      11     12  11  13     8
      6 2003       5      7   8   5     6
      7 2004      13     13  15  15    10
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多