2

groupごとに不一致のケースをどのように計算できるか疑問に思っていました。

これが私のデータであると想像してみましょう:

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 = ''))

データはこんな感じ

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

のようなものを得るために

Group 1 : 0 
Group 2 : 1 

stringdistライブラリを使用してこれを計算することは素晴らしいことです。

何かのようなもの

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

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

しかし、それは機能していません。

何か案は ?

クイック更新: 重みの問題をどのように解決しますか? たとえば、2 つの文字の不一致を設定するときに、引数 (値 (1,2,3, ...)) を渡すにはどうすればよいでしょうか。同様に、b と cの間のミスマッチは2のコストがかかり、a とcの間のミスマッチは1などのコストがかかります。

4

5 に答える 5

6

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)
于 2015-07-07T23:53:40.850 に答える
3

以下のコードは、グループごとの不一致の数を示します。ここで、不一致は、グループの各レベルの各列 t1、t2 などの一意の値の数より 1 少ないものとして定義されます。不一致のバイナリ測定以上のものが必要な場合にのみ、文字列距離測定を導入する必要があると思いますが、あなたが示した例ではバイナリ測定で十分です。また、必要なのが各グループ内の個別の行数だけである場合、@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

dplyr個々の不一致をカウントするためのより短い方法を次に示します。再形成は必要ありませんが、他のデータ体操が必要です。

sek %>% as.data.frame %>%
  group_by(Group) %>%
  summarise_each(funs(length(unique(.)) - 1)) %>%
  mutate(mismatch = rowSums(.[-1])) %>%
  select(-matches("^t[1-3]$"))
于 2015-07-07T23:38:11.353 に答える
3

別のアイデア:

library(dplyr)
library(tidyr)

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

これにより、次のことが得られます。

#Source: local data frame [2 x 2]
#
#  Group dist
#1     1    0
#2     2    1
于 2015-07-07T23:48:52.460 に答える
2
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
于 2015-07-07T23:41:19.300 に答える
2

基本パッケージ:

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

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")

出力:

  Groups Dist
1      1    0
2      2    1
于 2015-07-10T10:15:05.403 に答える