我想按组应用一个函数,该函数根据该组中的值将观察值所属的间隔分配给新变量。我觉得以下代码应该可以工作,但是似乎正在使用整个数据集,而不是组的最大值和最小值。我想念什么?
#require(data.table)
#fake data
set.seed(12345)
df1 <- data.frame(id_f=c(rep("a a",100),rep("b b",100),rep("c c",100)),
L=c(abs(rnorm(100,50,20)),abs(rnorm(100,90,20)),abs(rnorm(100,220,20))),
w=abs(rnorm(300,6,3)))
dt2 = as.data.table(df1)
#the offending data.table function
dt2[,"bins":= findInterval(L, c((max(L)-min(L))/10*c(1:9)),left.open=T)+1, by=id_f]
编辑:
在“ aa”列中,在“ aa”范围内将有10个等距的bin,并且将为每个原始观测值分配一个bin编号,因为实际数据有6,000个观测值,每个观测值中都有多个成员斌因此输出将类似于:(为简洁起见,这是一个三个时间间隔的示例)
id_f L w bins
a a 1 1.0 1
a a 2 1.1 2
a a 3 5.0 3
b b 3 2.0 1
b b 6 3.5 2
b b 9 7.0 3
c c 10 1.0 1
c c 15 1.5 2
c c 20 6.0 3
我本以为我对findInterval
的调用将完成此任务,但是显然,它是从全局数据集中而不是仅从组中提取min
和max
的。我该如何从组中抢夺min
和max
,然后用它来计算该组的间隔?
答案 0 :(得分:1)
我认为在这里使用cut
会更容易,只需指定我们想要的breaks
的数量
library(data.table)
setDT(dt2)[,"bins":= cut(L, breaks = 10, labels = 1:10), by=id_f]
dt2
# id_f L w bins
# 1: a a 71.5 2.96 8
# 2: a a 49.5 3.63 5
# 3: a a 49.3 6.90 5
# 4: a a 19.7 10.92 2
# 5: a a 65.8 9.25 7
# ---
#296: c c 206.0 6.50 4
#297: c c 224.8 4.04 6
#298: c c 213.0 10.36 5
#299: c c 227.4 3.58 6
#300: c c 224.9 7.12 6
我们也可以在dplyr
或基数R中进行
library(dplyr)
dt2 %>%
group_by(id_f) %>%
mutate(bins = cut(L, breaks = 10, labels = 1:10))
OR
with(dt2, ave(L, id_f, FUN = function(x) cut(x, breaks = 10, labels = 1:10)))
答案 1 :(得分:0)
您将需要运行表格函数来演示该问题。 by
-操作似乎在“起作用”
> dt2[ , list(mn=min(L), mx=max(L) ), by=id_f]
id_f mn mx
1: a a 5.462025 104.2456
2: b b 43.824476 138.4843
3: c c 168.075002 276.5598
> dt2[ , table(id_f, bins)]
bins
id_f 1 2 3 4 5 6 7 8 9 10
a a 3 5 10 10 19 13 21 10 4 5
b b 0 0 0 0 1 3 10 8 19 59
c c 0 0 0 0 0 0 0 0 0 100
很明显,由于您没有使用set.seed()
png(); par(mfrow=c(3,1)); tapply(df1$L, df1$id_f, hist); dev.off()