2011-01-03 17 views
4

特定の計測器の結果を含むデータフレームがあり、各行の合計を含む新しい列を作成したいとします。新しいデータを分析するたびに異なる数の計測器があるため、新しい列を行合計で動的に計算する関数が必要です。行合計を計算する関数のサブセット

Type Value 
1 A 10 
2 A 15 
3 A 20 
4 A 25 
5 B 30 
6 B 40 
7 B 50 
8 B 60 
9 B 70 
10 B 80 
11 B 90 

私の目標は、次のことを達成することです:

A B Total 
1 10 30 40 
2 15 40 55 
3 20 50 70 
4 25 60 85 
5  70 70 
6  80 80 
7  90 90 

私はさまざまな方法を試してみたが、この方法では、保持しているだけで私の問題は、ここに私のデータフレームは次のようになりますし

最も有望である:

myList <- list(a = c(10, 15, 20, 25), b = c(30, 40, 50, 60, 70, 80, 90)) 
tmpDF <- data.frame(sapply(myList, '[', 1:max(sapply(myList, length)))) 
> tmpDF 
    a b 
1 10 30 
2 15 40 
3 20 50 
4 25 60 
5 NA 70 
6 NA 80 
7 NA 90 
totalSum <- rowSums(tmpDF) 
totalSum <- data.frame(totalSum) 
tmpDF <- cbind(tmpDF, totalSum) 
> tmpDF 
    a b totalSum 
1 10 30  40 
2 15 40  55 
3 20 50  70 
4 25 60  85 
5 NA 70  NA 
6 NA 80  NA 
7 NA 90  NA 

この方法では、2つのデータフレームdifこの例では、 'rowSums'関数は間違った値を返します。それ以外にも、元のデータはリスト形式ではないので、私はそのような「解決策」を適用することはできません。

は、私はこの問題を過度に複雑だと思うので、私は、私は...「タイプ」に基づいてデータフレームから

  • サブセットデータ、
  • が異なるのこれらの個々のサブセットを挿入することができますどのように思っていました
  • 個々のサブセットの正しい合計である、このデータフレームに「合計」列を追加します。

Anは、この問題に複雑さを追加し、私は手動で「タイプ」(A、B、数十をサブセットする必要がないように、これは、関数にまたは他の方法で動的な方法で行われる必要があることですCなど)をデータフレームに追加します。ここで

は動作しません。これは、私がこれまで持っているものだが、私は一緒に考えている行を示しています。この上の任意の考えやアイデアを事前に

TotalDf <- function(x){ 
    tmpNumberOfTypes <- c(levels(x$Type)) 
    for(i in tmpNumberOfTypes){ 
     subSetofData <- subset(x, Type = i, select = Value) 
     if(i == 1) { 
     totalDf <- subSetOfData } 
     else{ 
     totalDf <- cbind(totalDf, subSetofData)} 
    } 
    return(totalDf) 
} 

おかげで、

よろしく、ヨリスのコメントに

EDIT: 

おかげで私のデータフレームに彼のソリューションを翻訳しようとしたときしかし、私は追加に実行し、私は右方向の端部を得た(下記参照)問題。彼の提案の答え作品、と私にAの値は、以下の(正しい)の和を与え、B:私は私のデータフレームに、このソリューションをしようとすると、

> tmp78 <- tapply(DF$value,DF$id,sum) 
> tmp78 
1 2 3 4 5 6 
6 8 10 12 9 10 
> data.frame(tmp78) 
    tmp78 
1  6 
2  8 
3 10 
4 12 
5  9 
6 10 

しかし、それは動作しません:

私はサークルで周りつもり不穏な考えを持っている
> subSetOfData <- copyOfTradesList[c(1:3,11:13),c(1,10)] 
> subSetOfData 
    Instrument AccountValue 
1   JPM   6997 
2   JPM   7261 
3   JPM   7545 
11  KFT   6992 
12  KFT   6944 
13  KFT   7069 
> unlist(sapply(rle(subSetOfData$Instrument)$lengths,function(x) 1:x)) 
Error in rle(subSetOfData$Instrument) : 'x' must be an atomic vector 
> subSetOfData$InstrumentNumeric <- as.numeric(subSetOfData$Instrument) 
> unlist(sapply(rle(subSetOfData$InstrumentNumeric)$lengths,function(x) 1:x)) 
    [,1] [,2] 
[1,] 1 1 
[2,] 2 2 
[3,] 3 3 
> subSetOfData$id <- unlist(sapply(rle(subSetOfData$InstrumentNumeric)$lengths,function(x) 1:x)) 
Error in `$<-.data.frame`(`*tmp*`, "id", value = c(1L, 2L, 3L, 1L, 2L, : 
    replacement has 3 rows, data has 6 

...

+0

あなたはfigurあなた自身のエッセンスは要因に作用しません。しかし、奇妙なことがあります。私はあなたのエラーを再現することはできません、それは私のために正常に動作します。 R 2.12.1にアップデートしましたか?いずれにしても、plyrをインストールする際に内部エラーが発生した場合は、Rを再インストールするのに2分を費やすのが賢明でしょう。実際にはそれよりも時間がかかりません。 –

+0

@Joris:私は常に最新版に更新しませんでした。なぜなら、私はいつもそれらのものでは少し躊躇しているからです(2分は更新を保証するのに十分な励みになります:)。 'plyrエラー'や 'unlist'関数のエラーを再現するのに問題はありますか?私は本当に前者を望んでいます、そうでなければバージョン2.12.1 contra 2.11のRの標準機能に違いがあることを示唆しています。 – Jura25

+1

私はどちらも再現できませんが、私はunlist関数を参照していました。私は2.12が実際に2.11とは少し違って動作することを確認できますが、私が見つけたすべての変更はより良いものでした。 2.12.1はスムーズに実行されており、私が知っているすべてについては不具合があります。更新は間違いなく良い選択です。 –

答えて

3

つの思考:

1)あなたはna.rmを使用することができます= T rowSums

2)どの人がどの人と行かなければならないのか、どのように分かりますか?インデックスを追加することもできます。

例:

DF <- data.frame(
    type=c(rep("A",4),rep("B",6)), 
    value = 1:10, 
    stringsAsFactors=F 
) 


DF$id <- unlist(lapply(rle(DF$type)$lengths,function(x) 1:x)) 

今これはあなたが簡単にオリジナルのデータフレームに

tapply(DF$value,DF$id,sum) 

を合計しtapplyそして、もっと重要なのは、正しい形式であなたのデータフレームを取得することができます:

> DF 
    type value id 
1  A  1 1 
2  A  2 2 
3  A  3 3 
4  A  4 4 
5  B  5 1 
6  B  6 2 
7  B  7 3 
8  B  8 4 
9  B  9 5 
10 B 10 6 

> library(reshape) 
> cast(DF,id~type) 
    id A B 
1 1 1 5 
2 2 2 6 
3 3 3 7 
4 4 4 8 
5 5 NA 9 
6 6 NA 10 
+0

Jorisさん、ありがとうございます。提案1は、合計行でNA問題を解決します。良い点は、2番目の提案です。マッチング(例えば、時間通り)は、さらなる分析のためのものであり、私は長い間その質問をしたくなかった。ただし、Aの最初の値がBの最初の値とほぼ同じ時間に発生したという意味ではすでに一致しています。 – Jura25

+0

@Jura:次にidを追加できます。私は単純なキャストを可能にする例で私の答えを適応させた。 –

+0

@Joris: "DF $ Total < - tapply(DF $ value、DF $ id、sum)"と入力するとエラーが発生します。 "$ < - 。data.frameのエラー(6L、8L、10L、12L、:置き換えは6行、データは10 "ですか、これは予期して変形するパッケージに依存していますか?私はplyrパッケージをインストールすることができないので(Rは内部エラーが発生します)、Rを削除して再インストールしないでください。このPlyrエラーを解決しようとすると、私にとっては絶対必要です – Jura25

0
TV <- data.frame(Type = c("A","A","A","A","B","B","B","B","B","B","B") 
      , Value = c(10,15,20,25,30,40,50,60,70,80,90) 
      , stringsAsFactors = FALSE) 

# Added Type C for testing 
# TV <- data.frame(Type = c("A","A","A","A","B","B","B","B","B","B","B", "C", "C", "C") 
#     , Value = c(10,15,20,25,30,40,50,60,70,80,90, 100, 150, 130) 
#     , stringsAsFactors = FALSE) 

lnType <- with(TV, tapply(Value, Type, length)) 
lnType <- as.integer(lnType) 
lnType 

id <- unlist(mapply(FUN = rep_len, length.out = lnType, x = list(1:max(lnType)))) 
(TV <- cbind(id, TV)) 

require(reshape2) 
tvWide <- dcast(TV, id ~ Type) 

# Alternatively 
# tvWide <- reshape(data = TV, direction = "wide", timevar = "Type", ids = c(id, Type)) 

tvWide <- subset(tvWide, select = -id) 

# If you want something neat without the <NA> 
# for(i in 1:ncol(tvWide)){ 
# 
#  if (is.na(tvWide[j,i])){ 
#  tvWide[j,i] = 0 
#  } 
#  
# } 
# } 

tvWide 
transform(tvWide, rowSum=rowSums(tvWide, na.rm = TRUE)) 
関連する問題