【问题标题】:Summarize a factor variable by combinations of second factor variable通过第二个因素变量的组合来总结一个因素变量
【发布时间】:2018-06-27 14:50:49
【问题描述】:

我的数据是这样的

set.seed(89)
d <- data.frame(
  ID=seq(1, 100),
  Encounter=sample(c(1:50), 100, replace = TRUE), 
  EffortType=sample(c("A","B","C"), 100, replace = TRUE)
)

我认为 Encounter 变量是一个因素。

我想知道 EffortType 可能组合的频率。

我希望结果看起来像这样

EffortType      N
A               8
B               8
C               9
A,B             4
A,C             8
B,C             5
A,B,C           3

我还希望能够通过 EffortType 组合对数据进行子集化。例如,我最终会得到一个 EffortType A,B 的子集,看起来像这样

ID  Encounter    EffortType    
52  2            A
53  2            B
61  2            A
63  2            A
79  2            A
36  7            B
59  7            B
83  7            A
etc.

我确实尝试过重塑数据,以便我使用“mutate”为每个 EffortType 级别设置单独的变量,然后尝试计算每个组合的实例,但没有正确执行此操作,如下所示。在计数之前,我无法弄清楚如何通过遭遇“分组”。

d = mutate(d, 
              A = ifelse(grepl("A", EffortType), T, F),
              B = ifelse(grepl("B", EffortType), T, F),
              C = ifelse(grepl("C", EffortType), T, F))

d = data.table(d)
d[, .N, by = c('Encounter', 'A', 'B', 'C')]

但我最终没有得到我希望的摘要。请帮忙。谢谢。

【问题讨论】:

  • 在产生可重复性的随机数据之前 set.seed() 是个好主意
  • 感谢您的提示 - 我添加了 set.seed() 并使“希望”的结果匹配。

标签: r summary


【解决方案1】:

这是您第一个问题的答案:

> library(tidyverse)
> d %>% arrange(Encounter) %>% 
    group_by(Encounter) %>% 
    distinct(EffortType) %>% 
    arrange(EffortType) %>% 
    summarize(Efforts=paste(EffortType,collapse=",")) %>% 
    group_by(Efforts) %>% tally()
# A tibble: 7 x 2
  Efforts     n
  <chr>   <int>
1 A           6
2 A,B         7
3 A,B,C       6
4 A,C         9
5 B           6
6 B,C         5
7 C           4

如果您将d 的上述处理保存为名为@9​​87654323@ 的数据框,您可以根据每个努力组合对数据进行子集化,例如对于ABz$Efforts[2] 中的组合:

> d %>% filter(EffortType %in% unlist(strsplit(z$Efforts[2],split=",")))
   ID Encounter EffortType
1   1        43          B
2   2        15          B
3   3         8          B
4   4        36          A
5   6         2          B
6   7        50          A

如果要按EffortType 排序,请在末尾添加%&gt;% arrange(EffortType)

【讨论】:

  • 谢谢!第一部分我成功了。然后我确实将处理后的数据帧保存为“z”,然后运行最后一行代码,但改为按 Encounter 排序。我注意到结果包括一些实例,其中 Encounter 只有 A 或 B,以及同时遇到 A&B。
  • @heatherr 可以试试setequal(EffortType, unlist(strsplit(z$Efforts[2],split=",")))作为group_by(Encounter)之后的过滤条件。
【解决方案2】:

我会为遭遇属性制作一个单独的表格:

library(data.table)
EncounterDT = d[, 
  .(tt = paste(sort(unique(EffortType)), collapse=" "))
, keyby=Encounter]

# count encounters by types
EncounterDT[, .N, keyby=tt][order(nchar(tt), tt)]

# subset d using a join
d[EncounterDT[tt == "A B", .(Encounter)], on=.(Encounter)]

如果您非常喜欢使用单个表,但是...

# add a repeating-value column
d[, tt := paste(sort(unique(EffortType)), collapse=" "), by=Encounter]

# count encounters by types
d[, uniqueN(Encounter), keyby=tt][order(nchar(tt), tt)]

# subset d based using the tt column
d[tt == "A B"]

【讨论】:

  • 非常感谢!我正在尝试更多地使用 data.tables,非常喜欢这种方法。
  • 我可以用一个相关的问题麻烦您吗?我想在 d 中添加一个“物种”变量。然后,我想按遭遇列出物种,但按 EffortTypes 单独列。我尝试了 d[, .(tt = paste(sort(unique(Species)), collapse=" ")), keyby=Encounter] 并且无法弄清楚如何按 EffortType 进行拆分。
  • 所以我不想使用“tt”,而是使用“tA”和“tB”。
  • @heatherr 好问题。我会在 Encounter-EffortType 级别创建另一个表:res = d[, .(tt = paste(sort(unique(Species)), collapse=" ")), keyby=.(Encounter, EffortType)]。要使用您提到的列转换为“宽”形式,也许像 wres = dcast(res, Encounter ~ EffortType) 这样的东西会起作用,或者将它与另一个表结合起来......EncounterDT[, (new_cols) := wres[, -1]]
猜你喜欢
  • 2014-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多