我有一个相对较大的数据集(16,000 + x~31)。换句话说,它足够大,我不想在Excel中逐行操作它。数据采用以下形式:
block site day X1 X2
1 1 1 0.4 5.1
1 1 2 0.8 1.1
1 1 3 1.1 4.2
1 2 1 ... ...
1 2 2
1 2 3
2 3 1
2 3 2
2 3 3
2 4 1
2 4 2
2 4 3
正如您所看到的,网站计数是连续的,但我想要一个列,其中站点编号与每个块重置。例如,我想要下面这样的东西:
block site day X1 X2 site2
1 1 1 0.4 5.1 1
1 1 2 0.8 1.1 1
1 1 3 1.1 4.2 1
1 2 1 ... ... 2
1 2 2 2
1 2 3 2
2 3 1 1
2 3 2 1
2 3 3 1
2 4 1 2
2 4 2 2
2 4 3 2
我正在考虑使用R功能但是我不确定它是否会因为白天的并发症而起作用。否则,我会尝试类似的事情:
Data$site2 <- sequence(rle(Data$block)$lengths)
是否有人建议添加列计数(序列)每个块内的网站数量?如果有帮助,每个站点记录的天数(263)相同,但每个站点的站点数量不同。
答案 0 :(得分:6)
使用 plyr 和ddply
,这是一个略显笨拙的解决方案:
ddply(df,.(block),transform,
site1 = rep(1:length(unique(site)),
times = rle(site)$lengths))
或略微光滑的版本:
ddply(df,.(block),transform,site1 = as.integer(as.factor(site)))
但是,使用各种seq
,sequence
和rle
函数可能会有一种巧妙的方法直接执行此操作,但此刻我的大脑有点朦胧。如果你把这个打开一点,有人可能会带来一个光滑的非plyr
解决方案。
答案 1 :(得分:1)
使用tapply可以正常工作
# Make some fake data
dat <- data.frame(block = rep(1:3, each = 4), site = rep(1:6, each = 2), val = rnorm(12))
# For each block reset the count
dat$site2 <- unlist(tapply(dat$site, dat$block, function(x){x - min(x) + 1}))
答案 2 :(得分:0)
通过ave:
df1 <- structure(list(block = c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2),
site = c(1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4), day = c(1,
2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3)), .Names = c("block", "site",
"day"), row.names = c("2", "3", "4", "5", "6", "7", "8", "9",
"10", "11", "12", "13"), class = "data.frame")
df1$site2 <- ave(df1$site,df1$block,FUN=function(x) match(x,sort(unique(x))))
答案 3 :(得分:0)
我只是想使用dplyr更新一个答案,以实现@joran的方法为现在发现这个问题的人。
library(dplyr)
# create data
df <- data.frame(block = rep(1:3, each = 4),
site = rep(1:6, each = 2),
day = rep(1:2, times = 6),
x = rnorm(12))
df %>%
group_by(block) %>%
mutate(site2 = as.integer(as.factor(site)))
结果输出为:
block site day x site2
<int> <int> <int> <dbl> <int>
1 1 1 0.762 1
1 1 2 -0.612 1
1 2 1 1.06 2
1 2 2 -0.168 2
2 3 1 1.09 1
2 3 2 1.38 1
2 4 1 1.69 2
2 4 2 0.414 2
3 5 1 0.208 1
3 5 2 -0.647 1
3 6 1 -1.01 2
3 6 2 -0.354 2