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つのデータフレームを組み合わせることができたとしても、この例では「rowSums」関数が間違った値を返します。その上、私の元のデータはリスト形式ではないので、そのような「解決策」を適用することはできません。

私はこの問題を複雑にしすぎていると思うので、どうすればよいのか疑問に思いました…</ p>

  • 「タイプ」に基づいてデータフレームからデータをサブセット化し、
  • 異なる長さのこれらの個々のサブセットを新しいデータフレームに挿入します。
  • 個々のサブセットの正しい合計である「合計」列をこのデータフレームに追加します。

この問題に追加された複雑さは、これを関数またはその他の動的な方法で実行する必要があるため、数十の「タイプ」(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:

Jorisのコメント(以下を参照)のおかげで、私は正しい方向に終わりましたが、彼のソリューションを私のデータフレームに変換しようとすると、追加の問題が発生します。彼の提案した答えはうまくいき、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

私は輪になって回っているという気がかりな考えを持っています…</p>

4

2 に答える 2

3

2つの考え:

1)rowSumsでna.rm=Tを使用できます

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これにより、元のデータフレームの合計を簡単に作成できます

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

そして、さらに重要なのは、データフレームを正しい形式で取得することです。

> 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
于 2011-01-03T10:15:31.003 に答える
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))
于 2016-07-11T14:17:03.010 に答える