2012-09-11 13 views
8

短いバージョン:データフレーム内の値を別のデータフレーム内の文字列に置き換えるにはどうすればよいですか?データフレーム内の値をRの文字列に置き換えるにはどうすればよいですか?

より長いバージョン:私は多くの種のミツバチを扱う生物学者です。私は何千ものミツバチのデータセットを持っています。各行には、その標本に関するすべての関連情報(捕捉のデータ、GPSの位置など)とともに固有の蜂のID番号が付いています。各蜂の種情報は、それらを識別するのに長い時間がかかるので、入力されていません。私がIDingするとき、私は同じ種類のすべてのミツバチの箱で終わります。私はこれらを別のデータフレームに入力します。私はミツバチのIDとして、種情報(家族、属、種、性別など)を元のデータファイルに更新するコードを記述しようとしています。現在のところ、元のデータファイルでは、種情報は空白で、R内のNAと解釈されます。Rにすべての固有の蜂のID番号を見つけて種情報を記入したいのですが、どのようにしかしと、私が欲しいよう

rawData<-data.frame(beeID=c(1:20),family=rep(NA,20)) 
speciesInfo<-data.frame(beeID=seq(1,20,3),family=rep("Andrenidae",7)) 

rawData[rawData$beeID == 4,"family"] <- speciesInfo[speciesInfo$beeID == 4,"family"] 

だから、私は物事を交換しています:ここで

は私がやろうとしています何の簡単な例である文字列(例えば「Andrenidae」)とNA値を置き換えます家族名(文字列)ではなく数字です。私は最終的にやりたいことは例えば、すべての種の情報を追加するには少しループを書く:何かアドバイスを事前に

for (i in speciesInfo$beeID){ 
    rawData[rawData$beeID == i,"family"] <- speciesInfo[speciesInfo$beeID == i,"family"] 
} 

感謝です!

乾杯、

ザック

編集:私は種の情報を複数回追加する必要がある場合

が、私はちょうど最初の2つの方法は、以下の問題を引き起こすことになる、毎回新しい列を追加することに気づきました(私が通常やっている)。例:

rawData<-data.frame(beeID=c(1:20),family=rep(NA,20)) 
Andrenidae<-data.frame(beeID=seq(1,20,3),family=rep("Andrenidae",7)) 
Halictidae<-data.frame(beeID=seq(1,20,3)+1,family=rep("Halictidae",7)) 

# using join 
library(plyr) 
rawData <- join(rawData, Andrenidae, by = "beeID", type = "left") 
rawData <- join(rawData, Halictidae, by = "beeID", type = "left") 

# using merge 
rawData <- merge(x=rawData,y=Andrenidae,by='beeID',all.x=T,all.y=F) 
rawData <- merge(x=rawData,y=Halictidae,by='beeID',all.x=T,all.y=F) 

1つの統一データフレームを持つように列を折りたたむ方法はありますか?または毎回新しい列を追加するのではなく、rawDataを更新する方法ですか?前もって感謝します!

答えて

2

merge関数を使用できます。たとえば、次のようになります。 :

rawData <- data.frame(beeID=c(1:20),family=rep(NA,20)) 
speciesInfo <- data.frame(beeID=seq(1,20,3), 
          family=c(rep('Halictidae',4), rep("Andrenidae",3))) 

merged <- merge(x=rawData,y=speciesInfo,by='beeID',all.x=T,all.y=F) 
merged$family.x <- NULL # remove the family.x column 
names(merged) <- c('beeID','family') # rename the columns 

N.B.

列でrawDataを初期化する必要はありません。
マージ機能によって自動的に追加されます。 :

rawData <- data.frame(beeID=c(1:20)) 
speciesInfo <- data.frame(beeID=seq(1,20,3), 
          family=c(rep('Halictidae',4), rep("Andrenidae",3))) 

merged <- merge(x=rawData,y=speciesInfo,by='beeID',all.x=T,all.y=F) 

> merged 
    beeID  family 
1  1 Halictidae 
2  2  <NA> 
3  3  <NA> 
4  4 Halictidae 
5  5  <NA> 
6  6  <NA> 
7  7 Halictidae 
8  8  <NA> 
9  9  <NA> 
10 10 Halictidae 
11 11  <NA> 
12 12  <NA> 
13 13 Andrenidae 
14 14  <NA> 
15 15  <NA> 
16 16 Andrenidae 
17 17  <NA> 
18 18  <NA> 
19 19 Andrenidae 
20 20  <NA> 
+0

ワンダフル、おかげで興味を持っているデータです! – Arturito

3

別のオプションは、パッケージplyr

library(plyr) 
#Adding family ahead of time was unnecessary so I'll remove it alongside the join. 
join(rawData, speciesInfo, by = "beeID", type = "left")[,-2] 
    beeID  family 
1  1 Andrenidae 
2  2  <NA> 
3  3  <NA> 
4  4 Andrenidae 
5  5  <NA> 
6  6  <NA> 
7  7 Andrenidae 
8  8  <NA> 
9  9  <NA> 
10 10 Andrenidae 
11 11  <NA> 
12 12  <NA> 
13 13 Andrenidae 
14 14  <NA> 
15 15  <NA> 
16 16 Andrenidae 
17 17  <NA> 
18 18  <NA> 
19 19 Andrenidae 
20 20  <NA> 

?joinを使用することです更新

# If you anticipate adding new species over time, 
# simply rbind those into a single reference data.frame to merge with your rawData. 
# Like so: 
library(plyr) 
rawData <- join(rawData, rbind(Andrenidae, Halictidae), by = "beeID", type = "left") 

# To keep you code clean, you could do this step ahead of time 
species_list <- rbind(Andrenidae, Halictidae) 
rawData <- join(rawData, species_list, by = "beeID", type = "left") 
+0

素晴らしい!ありがとう! – Arturito

+0

返信にコードを含める方法がわかりませんでしたので、元の質問をフォローアップの質問で編集しました。私はいつもlurkerだったので、私はまだ貢献のハングを取得していない。任意のすべての助けをありがとう! – Arturito

+1

あなたの質問を編集してうれしいです(SOがどのように働いているか、つまり回答に基づいて質問を明確にして改善する)。編集した回答はあなたの新しい質問に対処する必要があります。データセットが大幅に大きくなる場合は、これに対してより強力なソリューションがあります。 – Maiasaura

4

ここで私はあなたのために働くだろうと思い関数です。これは、matchを使用してアノテーションデータフレームの値を検索し、次にrawDataの値を置き換えます。

replaceID <- function(to,from,mergeBy,values){ 
    x <- match(from[,mergeBy],to[,mergeBy]) 
    to[,values][x] <- as.character(from[,values]) 
    return(to) 
} 
> rawData <- replaceID(rawData,Halictidae,"beeID","family") 
> rawData 
    beeID  family 
1  1  <NA> 
2  2 Halictidae 
3  3  <NA> 
4  4  <NA> 
5  5 Halictidae 
6  6  <NA> 
7  7  <NA> 
8  8 Halictidae 
9  9  <NA> 
10 10  <NA> 
11 11 Halictidae 
12 12  <NA> 
13 13  <NA> 
14 14 Halictidae 
15 15  <NA> 
16 16  <NA> 
17 17 Halictidae 
18 18  <NA> 
19 19  <NA> 
20 20 Halictidae 
+0

これは完璧です、私が最初に想像していたものとまったく同じです。お手伝いありがとう!乾杯、ザック – Arturito

+0

ようこそ。ミツバチと幸運! –

2

data.table解決策はメモリと時間効率になります。あなたはrbindlistためstringsAsFactors = Fを持っている必要があります

  • 注意(do.callの超高速バージョン(rbind、リスト)/ rbind)
  • 私はrawDataオブジェクトにダミーデータとして別の列を追加しましたし、家族を削除しました。

データの作成 -

rawData <- data.frame(beeID = c(1:20), other_stuff = sample(letters, 20), stringsAsFactors = F) 
Andrenidae <- data.frame(beeID = seq(1, 20, 3), family = rep("Andrenidae", 7), stringsAsFactors = F) 
Halictidae <- data.frame(beeID = seq(1, 20 , 3)+ 1, family = rep("Halictidae", 7), stringsAsFactors = F) 
library(data.table) 
# convert to data.table 
rawDT <- as.data.table(rawData) 
# combine the list of Species-specific data.frames into a large data.table 
speciesInfo <- rbindlist(list(Andrenidae, Halictidae)) 
# set the keys, to allow efficient use of data.table and its merging 
# abilities. The keys are the same for both 
setkeyv(rawDT, 'beeID') 
setkeyv(speciesInfo, 'beeID') 
# merge by key 
speciesInfo[rawDT, nomatch = NA] 
## beeID  family other_stuff 
## 1:  1 Andrenidae   s 
## 2:  2 Halictidae   x 
## 3:  3   NA   i 
## 4:  4 Andrenidae   e 
## 5:  5 Halictidae   v 
## 6:  6   NA   q 
## 7:  7 Andrenidae   w 
## 8:  8 Halictidae   c 
## 9:  9   NA   u 
## 10: 10 Andrenidae   z 
## 11: 11 Halictidae   y 
## 12: 12   NA   a 
## 13: 13 Andrenidae   l 
## 14: 14 Halictidae   r 
## 15: 15   NA   h 
## 16: 16 Andrenidae   o 
## 17: 17 Halictidae   n 
## 18: 18   NA   g 
## 19: 19 Andrenidae   p 
## 20: 20 Halictidae   m 

または

rawDT[speciesInfo] 

## beeID other_stuff  family 
## 1:  1   s Andrenidae 
## 2:  2   x Halictidae 
## 3:  4   e Andrenidae 
## 4:  5   v Halictidae 
## 5:  7   w Andrenidae 
## 6:  8   c Halictidae 
## 7: 10   z Andrenidae 
## 8: 11   y Halictidae 
## 9: 13   l Andrenidae 
## 10: 14   r Halictidae 
## 11: 16   o Andrenidae 
## 12: 17   n Halictidae 
## 13: 19   p Andrenidae 
## 14: 20   m Halictidae 

今まであなたが助けを

関連する問題