0

我想resultdf水平方向创建一个数据集,为每个 region, state,组合单独的行创建一个数据集,county其中列被排序。yearcity

我还想通过 标识新数据集中的每一行regionstate并删除四列county之间的空白。results下面的代码完成了所有这些,但我怀疑它不是很有效。

有没有一种方法可以做到这一点,reshape2而无需为每个组创建唯一标识符并对每个组内的观察进行编号?有没有办法使用 apply 代替 for 循环从矩阵中删除空格?(此处使用矩阵的方式与数学或编程构造不同。)我意识到这是两个独立的问题,也许我应该分别发布每个问题。

鉴于我可以达到预期的结果并且只想改进代码,我不知道我是否应该发布这个,但我希望学习。感谢您的任何建议。

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

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

马修·伦德伯格的回答非常好。后来我意识到我还需要创建一个输出数据集,其中上面的四个结果列包含数字、有理数并用空格分隔。因此,在这里,我提供了一种明显的方法来使用 Matthew 的答案的修改来做到这一点。我不知道这是否是公认的协议,但新场景似乎与原始帖子直接相关,以至于我认为我不应该发布新问题。

前两行是对马修答案的修改。

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 回答
0

在我原来的帖子中,我询问了如何使用apply. 由于 Matthew Lundberg 对我更大问题的回答,这并没有被证明是必要的。尽管如此,删除数据集列之间的空格是我经常要做的事情。为了完整起见,我在这里发布了一种使用方法paste0apply部分来自马修的回答。

要从数据集中删除所有空格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

以下代码仅删除第二列和第三列之间的空格:

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 回答