我正在使用cut将数据划分为多个二进制文件,这样就可以生成垃圾箱(x1,x2].任何人都可以告诉我如何制作一个表达这些箱子作为箱子中点的新栏目?例如,使用以下数据帧:
structure(list(x = c(1L, 4L, 6L, 7L, 8L, 9L, 12L, 18L, 19L),
y = 1:9), .Names = c("x", "y"), class = "data.frame", row.names = c(NA,
-9L))
Run Code Online (Sandbox Code Playgroud)
我可以用
test$xRange <- cut(test$x, breaks=seq(0, 20, 5))
Run Code Online (Sandbox Code Playgroud)
给
x y xRange
1 1 1 (0,5]
2 4 2 (0,5]
3 6 3 (5,10]
4 7 4 (5,10]
5 8 5 (5,10]
6 9 6 (5,10]
7 12 7 (10,15]
8 18 8 (15,20]
9 19 9 (15,20]
Run Code Online (Sandbox Code Playgroud)
但我需要的结果应该是:
x y xRange xMidpoint
1 1 1 (0,5] 2.5
2 4 2 (0,5] 2.5
3 6 3 (5,10] 7.5
4 7 4 (5,10] 7.5
5 8 5 (5,10] 7.5
6 9 6 (5,10] 7.5
7 12 7 (10,15] 12.5
8 18 8 (15,20] 17.5
9 19 9 (15,20] 17.5
Run Code Online (Sandbox Code Playgroud)
我已经做了一些搜索,并在相同长度的箱子中划分了一系列值的类似问题:cut vs cut2,这给出了一个解决方案
cut2 <- function(x, breaks) {
r <- range(x)
b <- seq(r[1], r[2], length=2*breaks+1)
brk <- b[0:breaks*2+1]
mid <- b[1:breaks*2]
brk[1] <- brk[1]-0.01
k <- cut(x, breaks=brk, labels=FALSE)
mid[k]
}
Run Code Online (Sandbox Code Playgroud)
但是当我在我的案例中尝试这个时,使用
test$xMidpoint <- cut2(test$x, 5)
Run Code Online (Sandbox Code Playgroud)
它没有返回正确的中点.也许我错误地进入了休息时间cut2?谁能告诉我我做错了什么?
除非我错过了什么,否则这样的东西看起来是有效
brks = seq(0, 20, 5)
ints = findInterval(test$x, brks, all.inside = T)
#mapply(function(x, y) (x + y) / 2, brks[ints], brks[ints + 1]) #which is ridiculous
#[1] 2.5 2.5 7.5 7.5 7.5 7.5 12.5 17.5 17.5
(brks[ints] + brks[ints + 1]) / 2 #as sgibb noted
#[1] 2.5 2.5 7.5 7.5 7.5 7.5 12.5 17.5 17.5
(head(brks, -1) + diff(brks) / 2)[ints] #or using thelatemail's idea from the comments
#[1] 2.5 2.5 7.5 7.5 7.5 7.5 12.5 17.5 17.5
Run Code Online (Sandbox Code Playgroud)