【问题标题】:comparing two variables in the same column in R比较R中同一列中的两个变量
【发布时间】:2018-09-25 16:55:54
【问题描述】:

我有两列。一个有一个变量列表,例如"cat", "dog", "rat", "chicken" 另一个是第一次还是第二次访问宠物店。

visit_number    pet
      1         dog
      2         dog
      1         cat
      2         cat
      1         rat
      2         chicken

我希望比较R 中的两次访问之间的差异,例如intersect()setdiff()。基本上和这个问题一模一样:

Compare two lists in R

但是,我没有两个列表,但在一列中有两个变量,我似乎无法让代码工作。

我想要实现的是这样的功能,但它使用单列而不是两个列表(代码取自另一个问题):

xtab_set <- function(A,B){
    both    <-  union(A,B)
    inA     <-  both %in% A
    inB     <-  both %in% B
    return(table(inA,inB))
}

【问题讨论】:

  • 您是否总是有 2 次访问:1 次和 2 次,还是更多?
  • 不清楚这里的输出应该是什么...?有with(DF, xtab_set(pet[visit_number == 1], pet[visit_number == 2]))
  • “我希望比较 R 中两次访问之间的差异” - 问题是:有什么不同?您可以为每只宠物设置一个随时间变化的值,例如从 1 到 5 的生命值。然后,您可以计算两次访问之间宠物分数的变化。但是我不确定这就是你所追求的。
  • @Frank 非常感谢。那段代码很有效,我希望输出如何。
  • 请提供 3 组示例数据和预期输出。

标签: r comparison intersect


【解决方案1】:

坦率地说,输出矩阵不是很清楚。但是,您在评论中提到您正在“寻找每次访问中仅在访问一、访问二和两次访问中都发生的唯一个体动物的数量(计数)。”同样在您提供的文件中,有 3 次访问。我正在考虑三个访问。

以下代码将按访问显示唯一个体动物的数量以及在所有访问中出现的唯一个体动物的数量。

第 1 步。构建原始数据集

library(data.table)
df = data.table(visit_number = c(1, 1, 1, 2, 2, 2, 3, 3, 3, 3), 
                pet = c("Dog", "Rat", "Cat", "Dog", "Chicken", "Cat", "Dog", "Cat", "Fish", "Horse"))

第 2 步。创建一个可理解的列名向量以供将来参考

cols = c(paste0(rep("Visit", length(unique(df$visit_number))), unique(df$visit_number)))

第 3 步。创建宠物外观矩阵

df = dcast.data.table(df, pet ~ visit_number, value.var = "pet", fun.aggregate = length)
names(df)[-1] = cols # assign understandable column names

第 4 步。定义出现在所有访问中的宠物

df[, AllVisits := Reduce(`*`, .SD), .SDcols = cols]

它给出:

df
       pet Visit1 Visit2 Visit3 AllVisits
1:     Cat      1      1      1         1
2: Chicken      0      1      0         0
3:     Dog      1      1      1         1
4:    Fish      0      0      1         0
5:   Horse      0      0      1         0
6:     Rat      1      0      0         0

老鼠在第 1 次访问中是唯一的,鸡在第 2 次访问中是唯一的,鱼和马在第 3 次访问中是唯一的。猫和狗出现在所有访问中。

第 5 步。通过访问获取唯一数量的动物数量以及在所有访问中出现的唯一动物数量

idx = df[, Reduce(`+`, .SD) == 1, .SDcols = cols]
unlist(c(df[idx, lapply(.SD, function(x) sum(x)), .SDcols = cols], AllVisits = df[, sum(AllVisits)]))

结果是:

Visit1    Visit2    Visit3 AllVisits 
     1         1         2         2 

让我知道您是否正在寻找。

附:如果宠物可能在访问期间多次出现,代码将需要修改。

【讨论】:

  • 谢谢。它们可能会出现不止一次,但如果确实发生,这种情况很少见。
【解决方案2】:

如果我正确理解您的问题,这里是使用 dplyr 包中的函数的解决方案:

full_join(filter(df, visit_number == 1), filter(df, visit_number == 2), by = 'pet') %>%
    mutate(visit1 = !is.na(visit_number.x),
           visit2 = !is.na(visit_number.y),
           both = visit1 & visit2) %>% 
    select(-starts_with('visit_number'))

给予:

      pet visit1 visit2  both
1     dog   TRUE   TRUE  TRUE
2     cat   TRUE   TRUE  TRUE
3     rat   TRUE  FALSE FALSE
4 chicken  FALSE   TRUE FALSE

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多