我有一个带间隔定义的数据框:
ints <- read.table(header=T, sep=";", stringsAsFactors = FALSE, na.strings = 'NA', text="
minValue;minOperato;maxValue;maxOperator;class
3914;>=;NA;NA;[3914,Inf)
NA;NA;1373;<;[ -Inf,1373)
1373;>=;1806;<;[1373,1806)
2777;>=;3914;<;[2777,3914)
1806;>=;2777;<;[1806,2777)
")
第二个数据框,其值为x
,二进制变量为y
:
sd <- data.frame(x = runif(1000) * 5000, y = as.integer(runif(1000) > .5))
现在,我希望在sd
数据帧中为每个间隔获取0和1的数量,并将结果合并到ints
数据帧。
我以为我会使用cut
:
breaks <- c(-Inf, ints$minValue[order(ints$minValue)], Inf)
breaks <- breaks[!is.na(breaks)]
out <- as.data.frame.matrix(table(cut(sd$x, breaks, right = FALSE), sd$y))
不幸的是,out
中的时间间隔与我的ints
数据框中的时间间隔不一致(表示方式不同),因此我无法将out
加入ints
。
我知道我可能会在某个循环中使用sqldf
包或重新编码ints$x
来生成一些sql,但这会很慢。
答案 0 :(得分:3)
一种解决方案是用简单的id(序列)替换你的间隔。应该为int和out data.frames完成此操作。每个id标识一个间隔。一旦你这样做,合并是直截了当的。
## first I extract the intevals from ints in ordered manner
id <- !is.na(ints$minValue)&!is.na(ints$maxValue)
class_factor <-
c(ints$class[which(is.na(ints$minValue))],
ints$class[id][order(ints$minValue[id])],
ints$class[which(is.na(ints$maxValue))])
## add an id column that identify each interval in ints data.frame
ints <- merge(data.frame(class=class_factor,id = seq_along(class_factor)),ints)
## Do same thing in out uisng lables=FALSE as a cut argument
out <- as.data.frame.matrix(table(cut(sd$x, breaks, right = FALSE,
labels=FALSE), sd$y)) ## here the trick
## merge ints and out
merge(out,ints,by.x=0,by.y="id")
# Row.names 0 1 class minValue minOperato maxValue maxOperator
# 1 1 132 146 [ -Inf,1373) NA <NA> 1373 <
# 2 2 45 38 [1373,1806) 1373 >= 1806 <
# 3 3 98 99 [1806,2777) 1806 >= 2777 <
# 4 4 98 110 [2777,3914) 2777 >= 3914 <
# 5 5 125 109 [3914,Inf) 3914 >= NA <NA>