简体   繁体   English

R - 按组计算不匹配

[英]R - Compute Mismatch By Group

I was wondering how could I compute mismatching cases by group . 我想知道如何按组计算不匹配的情况。

Let us imagine that this is my data : 让我们想象这是我的数据:

sek = rbind(c(1, 'a', 'a', 'a'), 
        c(1, 'a', 'a', 'a'), 
        c(2, 'b', 'b', 'b'), 
        c(2, 'c', 'b', 'b'))

colnames(sek) <- c('Group', paste('t', 1:3, sep = ''))

The data look like this 数据看起来像这样

     Group t1  t2  t3 
[1,] "1"   "a" "a" "a"
[2,] "1"   "a" "a" "a"
[3,] "2"   "b" "b" "b"
[4,] "2"   "c" "b" "b"

In order to get something like 为了获得类似的东西

Group 1 : 0 
Group 2 : 1 

It would be fancy to use the stringdist library to compute this. 使用stringdist库来计算它是很奇怪的。

Something like 就像是

seqdistgroupStr = function(x) stringdistmatrix(x, method = 'hamming')

sek %>% 
  as.data.frame() %>% 
  group_by(Group) %>% 
  seqdistgroupStr() 

But it is not working. 但它没有用。

Any ideas ? 有任何想法吗 ?

Quick Update : How would you solve the question of weights? 快速更新 :您如何解决权重问题? For example, how could I pass an argument - a value (1,2,3, ...) - when setting the mistmatch between two characters. 例如,在两个字符之间设置错误匹配时,如何传递参数 - 值(1,2,3,...)。 Like the mismatch between b and c cost 2 while the mismatch between a and c cost 1 and so on. B和C 2的成本之间的不匹配 ,而a和c成本1等之间的不匹配

Here is another dplyr solution that does not require any transformation of the data into long/wide forms: 这是另一个dplyr解决方案,不需要将数据转换为长/宽形式:

library(dplyr)
sek = rbind(c(1, 'a', 'a', 'a'), 
            c(1, 'a', 'a', 'a'), 
            c(2, 'b', 'b', 'b'), 
            c(2, 'c', 'b', 'b')) %>%
    data.frame

colnames(sek) <- c('Group', paste('t', 1:3, sep = ''))

sek %>% 
    group_by(Group) %>%
    distinct(t1, t2, t3) %>%
    summarise(number_of_mismatches = n() - 1)

The code below will give you the number of mismatches by group, where a mismatch is defined as one less than the number of unique values in each column t1, t2, etc. for each level of Group. 下面的代码将按组给出不匹配的数量,其中不匹配定义为每个级别的每个级别t1,t2等中的唯一值的数量少一个。 I think you would need to bring in a string distance measure only if you need more than a binary measure of mismatch, but a binary measure suffices for the example you gave. 我认为只有当你需要的不仅仅是二进制不匹配度量时,你才需要引入一个字符串距离度量,但二进制度量就足以满足你给出的例子。 Also, if all you want is the number of distinct rows in each group, then @Alex's solution is more concise. 此外,如果你想要的只是每组中不同行的数量,那么@ Alex的解决方案更简洁。

library(dplyr)
library(reshape2)

sek %>% as.data.frame %>%
  melt(id.var="Group") %>%
  group_by(Group, variable) %>%
  summarise(mismatch = length(unique(value)) - 1) %>%
  group_by(Group) %>%
  summarise(mismatch = sum(mismatch))

  Group mismatch
1     1        0
2     2        1

Here's a shorter dplyr method to count individual mismatches. 这是一个更短的dplyr方法来计算个体不匹配。 It doesn't require reshaping, but it requires other data gymnastics: 它不需要重塑,但它需要其他数据体操:

sek %>% as.data.frame %>%
  group_by(Group) %>%
  summarise_each(funs(length(unique(.)) - 1)) %>%
  mutate(mismatch = rowSums(.[-1])) %>%
  select(-matches("^t[1-3]$"))

Another idea: 另一个想法:

library(dplyr)
library(tidyr)

data.frame(sek) %>%
  gather(key, value, -Group) %>%
  group_by(Group) %>%
  summarise(dist = n_distinct(value)-1)

Which gives: 这使:

#Source: local data frame [2 x 2]
#
#  Group dist
#1     1    0
#2     2    1
m <- matrix(apply(sek[,-1], 1, paste, collapse=''))
newdf <- as.data.frame(cbind(sek[,1], m))
names(newdf) <- c('Group', 'value')
newdf %>% group_by(Group) %>% summarize(count = length(unique(value))-1)
#  Group count
#1     1     0
#2     2     1

Base package: 基础包:

aggregate(cbind(dist = Groups) ~ Groups, 
          data = unique(sek), 
          FUN = function(x){NROW(x)-1})

With sqldf : 使用sqldf

library(sqldf)
df <- rbind(c(1, "a", "a", "a"), 
            c(1, "a", "a", "a"), 
            c(2, "b", "b", "b"), 
            c(2, "c", "b", "b"))
df <- as.data.frame(df)
colnames(df)[1] <- "Groups"
sqldf("SELECT Groups, COUNT(Groups)-1 AS Dist 
      FROM (SELECT DISTINCT * FROM df) 
      GROUP BY Groups")

Output: 输出:

  Groups Dist
1      1    0
2      2    1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM