0

result水平方向に列をピボットして、列がthenで順序付けられている組み合わせごとに個別のdf行を持つデータセットを作成し たいと考えています。regionstatecountyyearcity

また、新しいデータ セットの各行を で識別し、4 つの列の間の空白を削除したいと考えregionていstateます。以下のコードはそのすべてを行っていますが、あまり効率的ではないと思います。countyresults

reshape2各グループに一意の識別子を作成し、各グループ内の観測に番号を付けずにこれを行う方法はありますか? 行列から空白を削除するために for ループの代わりに apply を使用する方法はありますか? (ここでの行列は、数学またはプログラミング構造とは異なる方法で使用されています。) これらは 2 つの別個の質問であり、各質問を個別に投稿する必要があることを認識しています。

私は望ましい結果を達成でき、コードを改善することだけを考えているので、これを投稿する必要があるかどうかはわかりませんが、学びたいと思っています. アドバイスをありがとう。

df <- read.table(text= "
region   state    county city  year result
1          1        1      1     1     1
1          1        1      2     1     2
1          1        1      1     2     3
1          1        1      2     2     4
1          1        2      3     1     4
1          1        2      4     1     3
1          1        2      3     2     2
1          1        2      4     2     1
1          2        1      1     1     0
1          2        1      2     1    NA
1          2        1      1     2     0
1          2        1      2     2     0
1          2        2      3     1     2
1          2        2      4     1     2
1          2        2      3     2     2
1          2        2      4     2     2
2          1        1      1     1     9
2          1        1      2     1     9
2          1        1      1     2     8
2          1        1      2     2     8
2          1        2      3     1     1
2          1        2      4     1     0
2          1        2      3     2     1
2          1        2      4     2     0
2          2        1      1     1     2
2          2        1      2     1     4
2          2        1      1     2     6
2          2        1      2     2     8
2          2        2      3     1     3
2          2        2      4     1     3
2          2        2      3     2     2
2          2        2      4     2     2
", header=TRUE, na.strings=NA)

desired.result <- read.table(text= "
region   state    county results
1          1        1     1234
1          1        2     4321
1          2        1     0.00
1          2        2     2222
2          1        1     9988
2          1        2     1010
2          2        1     2468
2          2        2     3322
", header=TRUE, colClasses=c('numeric','numeric','numeric','character'))

# redefine variables for package reshape2 creating a unique id for each
# region, state, county combination and then number observations in
# each of those combinations

library(reshape2)

id.var <- df$region*100000 + df$state*1000 + df$county
obsnum <- sequence(rle(id.var)$lengths)

df2 <- dcast(df, region + state + county ~ obsnum, value.var = "result")

# remove spaces between columns of results matrix
# with a for-loop.  How can I use apply to do this?

x <- df2[,4:(4+max(obsnum)-1)]

# use a dot to represent a missing observation

x[is.na(x)] = '.'

x.cat = numeric(nrow(x))

for(i in 1:nrow(x)) {
  x.cat[i] = paste(x[i,], collapse="")
}

df3 <- cbind(df2[,1:3],x.cat)
colnames(df3) <- c("region", "state", "county", "results")
df3

df3 == desired.result

編集:

以下の Matthew Lundberg の回答は優れています。その後、上記の 4 つの結果列が数値の有理数を含み、スペースで区切られた出力データ セットも作成する必要があることに気付きました。そのため、マシューの回答を変更する明らかな方法を以下に投稿しました。これが承認されたプロトコルかどうかはわかりませんが、新しいシナリオは元の投稿に直接関連しているように見えるので、新しい質問を投稿する必要はないと思いました.

4

3 に答える 3

1

これはあなたが望むことだと思います:

df$result <- as.character(df$result)
df$result[is.na(df$result)] <- '.'


aggregate(result ~ county+state+region, data=df, paste0, collapse='')

  county state region result
1      1     1      1   1234
2      2     1      1   4321
3      1     2      1   0.00
4      2     2      1   2222
5      1     1      2   9988
6      2     1      2   1010
7      1     2      2   2468
8      2     2      2   3322

これは、データフレームが適切な順序でソートされていることに依存しています(あなたのものと同じです)。

于 2012-12-31T23:09:25.307 に答える
0

元の投稿で、を使用してデータ セット内の列間のスペースを削除する方法を尋ねましたapply。私のより大きな質問に対する Matthew Lundberg の回答のおかげで、それは必要であることが証明されませんでした。それにもかかわらず、データ セットの列間のスペースを削除することは、私が頻繁に行う必要があることです。paste0完全を期すために、ここに を使用してそれを行う方法を投稿しますapply。これは、一部はマシューの回答から生じました。

データセットからすべてのスペースを削除するにはx:

x <- read.table(text= "
A    B    C    D
1    1    1    1
1    1    2    2
1   NA    1    3
1    1    2    4
1    2    1    5
1    2   NA    6
1    2    1    7
1    2    2    8
", header=TRUE, na.strings=NA)

# use a dot to represent a missing observation

x[is.na(x)] = '.'

y <- as.data.frame(apply(x, 1, function(i) paste0(i, collapse='')))
colnames(y) <- 'result'
y

与えます:

  result
1   1111
2   1122
3   1.13
4   1124
5   1215
6   12.6
7   1217
8   1228

次のコードは、2 列目と 3 列目の間だけのスペースを削除します。

z <- as.data.frame(apply(x[,2:3], 1, function(i) paste0(i, collapse='')))

y <- data.frame(x[,1], z, x[,4])
colnames(y) <- c('A','BC','D')
y

与える:

  A BC D
1 1 11 1
2 1 12 2
3 1 .1 3
4 1 12 4
5 1 21 5
6 1 2. 6
7 1 21 7
8 1 22 8
于 2013-01-01T20:06:21.883 に答える
0

マシュー・ランドバーグの答えは素晴らしいです。その後、上記の 4 つの結果列が数値の有理数を含み、スペースで区切られた出力データ セットも作成する必要があることに気付きました。したがって、ここでは、マシューの回答を変更して、それを行うための明らかな方法を提供します。これが受け入れられたプロトコルかどうかはわかりませんが、新しいシナリオは元の投稿に直接関連しているように見えるので、新しい質問を投稿する必要はないと思いました.

最初の 2 行は、マシューの回答を修正したものです。

df$result[is.na(df$result)] <- 'NA'
df2 <- aggregate(result ~ county+state+region, data=df, paste)

次に、 がNA欠落している観測値を表すように指定し、これを使用applyして数値出力を取得します。

df2$result[df2$result=='NA'] = NA
new.df <- data.frame(df2[,1:3], apply(df2$result,2,as.numeric))

df元の投稿に示されている各値に 0.5 を追加したことに注意してください。

  county state region  X1  X2  X3  X4
     1     1      1   1.5 2.5 3.5 4.5
     2     1      1   4.5 3.5 2.5 1.5
     1     2      1   0.5  NA 0.5 0.5
     2     2      1   2.5 2.5 2.5 2.5
     1     1      2   9.5 9.5 8.5 8.5
     2     1      2   1.5 0.5 1.5 0.5
     1     2      2   2.5 4.5 6.5 8.5
     2     2      2   3.5 3.5 2.5 2.5
于 2013-01-01T12:01:42.577 に答える