0

次のようにデータセットをレイアウトした場合:

Cohort Food1 Food2 Food 3 Food 4
--------------------------------
Group   1     1     2       3
 A      1     1     0       1
 B      0     0     1       0
 C      1     1     0       1
 D      0     0     0       1

各行を合計したいので、食品グループをさまざまなカテゴリに定義できます。そこで、グループ行を定義ベクトルとして使用したいと思います。

つまり、food1とfood2はグループ1にあり、food3はグループ2にあり、food4はグループ3にあります。

次のような理想的な出力:

Cohort Group1 Group2 Group3
 A      2       0      1
 B      0       1      0
 C      2       0      1
 D      0       0      1

このrowsum()ベースの関数を使用してみましたが、運が悪かったので、代わりにddply()を使用する必要がありますか?

コメントからのデータ例:

dat <-
structure(list(species = c("group", "princeps", "bougainvillei", 
"hombroni", "lindsayi", "concretus", "galatea", "ellioti", "carolinae", 
"hydrocharis"), locust = c(1L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 
0L), grasshopper = c(1L, 0L, 0L, 1L, 0L, 0L, 1L, 0L, 1L, 0L), 
    snake = c(2L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L), fish = c(2L, 
    1L, 0L, 1L, 1L, 0L, 1L, 0L, 1L, 0L), frog = c(2L, 0L, 0L, 
    0L, 0L, 0L, 0L, 1L, 0L, 0L), toad = c(2L, 0L, 0L, 0L, 0L, 
    1L, 0L, 0L, 0L, 0L), fruit = c(3L, 0L, 0L, 0L, 0L, 1L, 1L, 
    0L, 0L, 0L), seed = c(3L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 
    0L)), .Names = c("species", "locust", "grasshopper", "snake", 
"fish", "frog", "toad", "fruit", "seed"), class = "data.frame", row.names = c(NA, 
-10L))
4

2 に答える 2

2

より直接的なアプローチがある可能性が最も高いですが、ここにあなたが試すことができるものがあります:

  1. 最初に、2 番目のヘッダー行を除いたデータのコピーを作成します。

    dat2 <- dat[-1, ]
    
  2. melt()「reshape2」パッケージのなどdcast()は、重複した列名ではうまく機能しないため、列名をより「reshape2 に適した」ものにしましょう。

    Seq <- ave(as.vector(unlist(dat[1, -1])), 
               as.vector(unlist(dat[1, -1])), 
               FUN = seq_along)
    names(dat2)[-1] <- paste("group", dat[1, 2:ncol(dat)], 
                             ".", Seq, sep = "")
    
  3. melt()データセット

    m.dat2 <- melt(dat2, id.vars="species")
    
  4. 関数を使用してcolsplit()、列を正しく分割します。

    m.dat2 <- cbind(m.dat2[-2], 
                    colsplit(m.dat2$variable, "\\.", 
                             c("group", "time")))
    head(m.dat2)
    #         species value  group time
    # 1      princeps     0 group1    1
    # 2 bougainvillei     0 group1    1
    # 3      hombroni     1 group1    1
    # 4      lindsayi     0 group1    1
    # 5     concretus     0 group1    1
    # 6       galatea     0 group1    1
    
  5. dcast()いつも通りに進みます

    dcast(m.dat2, species ~ group, sum)
    #         species group1 group2 group3
    # 1 bougainvillei      0      0      0
    # 2     carolinae      1      1      0
    # 3     concretus      0      2      2
    # 4       ellioti      0      1      0
    # 5       galatea      1      1      1
    # 6      hombroni      2      1      0
    # 7   hydrocharis      0      0      0
    # 8      lindsayi      0      1      0
    # 9      princeps      0      1      0
    

:元の回答が間違っていたため編集しました。

更新: ベース R でのより簡単な方法

この問題は、データを転置することから始めると、はるかに簡単に解決できます。

dat3 <- t(dat[-1, -1])
dat3 <- as.data.frame(dat3)
names(dat3) <- dat[[1]][-1]
t(do.call(rbind, lapply(split(dat3, as.numeric(dat[1, -1])), colSums)))
#               1 2 3
# princeps      0 1 0
# bougainvillei 0 0 0
# hombroni      2 1 0
# lindsayi      0 1 0
# concretus     0 2 2
# galatea       1 1 1
# ellioti       0 1 0
# carolinae     1 1 0
# hydrocharis   0 0 0
于 2012-10-08T19:11:13.233 に答える
1

これは、ベース R を使用してかなり簡単に行うことができます。これが例です。

まず、どの動物がどのグループに属しているかを調べます。

groupings <- as.data.frame(table(as.numeric(dat[1,2:9]),names(dat)[2:9]))

attach(groupings)
grp1 <- groupings[Freq==1 & Var1==1,2]
grp2 <- groupings[Freq==1 & Var1==2,2]
grp3 <- groupings[Freq==1 & Var1==3,2]
detach(groupings)

次に、グループを使用しrowSums()て、正しい列に対して a を実行します。

dat <- cbind(dat,rowSums(dat[as.character(grp1)]))
dat <- cbind(dat,rowSums(dat[as.character(grp2)]))
dat <- cbind(dat,rowSums(dat[as.character(grp3)]))

最初の行と中間の列を削除します。

dat <- dat[-1,-c(2:9)]

次に、名前を正しく変更します。

row.names(dat) <- rm()
names(dat) <- c("species","group_1","group_2","group_3")

最終的には次のようになります。

      species group_1 group_2 group_3
bougainvillei       0       0       0
    carolinae       1       1       0
    concretus       0       2       2
      ellioti       0       1       0
      galatea       1       1       1
     hombroni       2       1       0
  hydrocharis       0       0       0
     lindsayi       0       1       0
     princeps       0       1       0

EDITED:他の回答と同様に、ソート順をアルファベット順に変更しました。

于 2012-10-08T20:12:03.310 に答える