我想result
在df
水平方向创建一个数据集,为每个
region
, state
,组合单独的行创建一个数据集,county
其中列被排序。year
city
我还想通过 标识新数据集中的每一行region
,state
并删除四列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 下面的回答非常好。后来我意识到我还需要创建一个输出数据集,其中上面的四个结果列包含数字、有理数并用空格分隔。因此,我在下面发布了一种明显的方法来修改马修的答案。我不知道这是否是公认的协议,但新场景似乎与原始帖子直接相关,以至于我认为我不应该发布新问题。