比较R中同一列中的两个变量

时间:2018-09-25 16:55:54

标签: r comparison intersect

我有两栏。一个有一个变量列表,例如“猫”,“狗”,“鼠”,“鸡”,另一个是在第一次或第二次旅行中是否参观过宠物店。

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 个答案:

答案 0 :(得分:1)

坦白说,输出矩阵不是很清楚。但是,您在评论中提到,您正在“寻找每次访问中唯一一次访问的唯一动物的数量(数量),仅在访问一次时出现,仅在访问两次时出现,而在两次访问中都发生。”此外,您提供的文档中还有三回。我正在考虑三次访问。

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

步骤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 

让我知道您是否正在寻找

P.S。如果宠物在访问期间可能出现几次,则需要对代码进行修改。

答案 1 :(得分:0)

如果我理解您的要求是正确的,这是使用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