1

我有一个数据框,其中的个人分配了一个文本 id,该文本 id 将地名与个人 id 连接起来(参见下面的数据)。最终,我需要将数据集从“长”转换为“宽”(例如,使用“重塑”),以便每个人只包含一行。为了做到这一点,我需要分配一个“时间”变量,reshape 可以使用它来识别随时间变化的协变量等。我有(可能是坏的)代码来为重复最多两次的个人执行此操作,但需要能够识别多达 18 次重复出现。如果我删除哈希前面的行,下面的代码可以正常工作,但最多只能识别两次重复。如果我把那条线留在里面(这对于重复两次以上的人来说似乎是必要的),R 会窒息,

Error in if (data$uid[i] == data$uid[i - 2]) { : 
  argument is of length zero

有人能帮忙吗?提前致谢!

place <- rep("ny",10)
pid <- c(1,1,2,2,2,3,4,4,5,5)
uid<- paste(place,pid,sep="")
time <- rep(0,10)
data <- cbind(uid,time)
data <- as.data.frame(data)
data$time <- as.numeric(data$time)

#bad code
data$time[1] <- 1 #need to set first so that loop doesn't go to a row that doesn't exist     (i.e., row 0)
for (i in 2:NROW(data)){
    data$time[i] <- 1 #set first occurrence to 1
    if (data$uid[i] == data$uid[i-1]) {data$time[i] <- 2} #set second occurrence to 2, etc.
    #if (data$uid[i] == data$uid[i-2]) {data$time[i] <- 3}
    i <- i+1
}
4

4 回答 4

2

目前尚不清楚您要做什么,但我认为您是在说您需要为每个唯一的每一行创建一个时间索引uid。那正确吗?

如果是这样,试一试

library(plyr)
ddply(data, "uid", transform, time = seq_along(uid))

会给你类似的东西:

   uid time
1  ny1    1
2  ny1    2
3  ny2    1
4  ny2    2
5  ny2    3
....
于 2011-10-06T01:51:10.790 回答
1

这是你的想法吗?

> d <- data.frame(uid = paste("ny",c(1,2,1,2,2,3,4,4,5,5),sep=""))
> out <- do.call(rbind, lapply(split(d, d$uid), function(x) {x$time <- 1:nrow(x); x}))
> rownames(out) <- NULL
> out
   uid time
1  ny1    1
2  ny1    2
3  ny2    1
4  ny2    2
5  ny2    3
6  ny3    1
7  ny4    1
8  ny4    2
9  ny5    1
10 ny5    2
于 2011-10-06T01:52:11.777 回答
0

在大型数据集上尝试了上述解决方案后,我决定为此编写自己的循环。这非常耗时,并且仍然需要将数据分解为 50k 元素的向量,但它最终确实奏效了:

system.time( for(i in 2:length(data$uid)) {
if(data$uid[i]==data$uid[i-1]) data$repeats[i] <- data$repeats[i-1]+1
  if ((i %% 1000)== 0) { #helps to keep track of how far the loop has gotten
    print(i) }
    i+1
}
)

感谢大家的帮助。

于 2011-10-26T01:08:42.473 回答
0

使用您的数据框设置:

place <- rep("ny",10)
pid <- c(1,1,2,2,2,3,4,4,5,5)
uid<- paste(place,pid,sep="")
time <- rep(0,10)
data <- cbind(uid,time)
data <- as.data.frame(data)

您可以使用:

data$time <- sequence(table(data$uid))
data

要得到:

> data
   uid time
1  ny1    1
2  ny1    2
3  ny2    1
4  ny2    2
5  ny2    3
6  ny3    1
7  ny4    1
8  ny4    2
9  ny5    1
10 ny5    2

注意:您的 data.frame 必须首先按 uid 排序才能正常工作。

于 2011-10-12T03:20:51.553 回答