有没有办法通过索引将数据绑定到data.frame? 比方说,我遇到了这样的情况 用户id=c(1:5,1:5) 时间=c(1:10) 访问日志=data.frame(用户id,时间) #我写了一个计算时间间隔的方法 间隔
我们可以使用有没有办法通过索引将数据绑定到data.frame? 比方说,我遇到了这样的情况 用户id=c(1:5,1:5) 时间=c(1:10) 访问日志=data.frame(用户id,时间) #我写了一个计算时间间隔的方法 间隔,r,R,我们可以使用diff()函数替换您的循环,该函数计算向量中相邻索引之间的差异,例如: #For say, I got a situation like this user_id = c(1:5,1:5) time = c(1:10) visit_log = data.frame(user_id, time) #And I've wrote a method to calculate interval interval <- function(data) { interval =
diff()
函数替换您的循环,该函数计算向量中相邻索引之间的差异,例如:
#For say, I got a situation like this
user_id = c(1:5,1:5)
time = c(1:10)
visit_log = data.frame(user_id, time)
#And I've wrote a method to calculate interval
interval <- function(data) {
interval = c(Inf)
for (i in seq(1, length(data$time))) {
intv = data$time[i]-data$time[i-1]
interval = append(interval, intv)
}
data$interval = interval
return (data)
}
#But when I want to get intervals by user_id and bind them to the data.frame,
#I can't find a proper way
#Is there any method to get something like
new_data = merge(by(visit_log, INDICE=visit_log$user_id, FUN=interval))
#And the result should be
user_id time interval
1 1 1 Inf
2 2 2 Inf
3 3 3 Inf
4 4 4 Inf
5 5 5 Inf
6 1 6 5
7 2 7 5
8 3 8 5
9 4 9 5
10 5 10 5
为此,我们可以通过c(Inf,diff(x))
预先添加Inf
接下来我们需要将上述内容分别应用于每个用户id
。为此,有很多选择,但这里我使用了aggregate()
。令人困惑的是,此函数返回一个数据帧,其中包含一个本身是矩阵的time
组件。我们需要将该矩阵转换为向量,这取决于在R中,矩阵列首先被填充的事实。最后,我们根据函数的原始版本向输入数据添加andinterval
列
> diff(c(1,3,6,10))
[1] 2 3 4
你能给出一个最小的可复制的例子吗?user_id=c(1:5,1:5),time=c(1:10)你的
interval()
函数不是很有效,你不应该在这样的循环中展开/连接,因为R必须在循环的每次迭代中复制和放大对象。你还需要以一种矢量化的方式来思考,以获得R的最佳效果。我可以在这里补充一个问题吗。你使用within()和direct assignment x$interval@iano有什么区别吗?是的,within()
比direct assignment慢,除此之外,没有。我倾向于使用within()或within()),因为它使代码更干净,代码的意图也比到处散布更清晰,但在这里可能是杀伤力过大和
x$interval
interval <- function(x) {
diffs <- aggregate(time ~ user_id, data = x, function(y) c(Inf, diff(y)))
diffs <- as.numeric(diffs$time)
x <- within(x, interval <- diffs)
x
}
> visit_log = data.frame(user_id = rep(1:5, 3), time = 1:15)
> interval(visit_log)
user_id time interval
1 1 1 Inf
2 2 2 Inf
3 3 3 Inf
4 4 4 Inf
5 5 5 Inf
6 1 6 5
7 2 7 5
8 3 8 5
9 4 9 5
10 5 10 5
11 1 11 5
12 2 12 5
13 3 13 5
14 4 14 5
15 5 15 5