在数据表中,比较行并在R中进行无循环的计算

时间:2017-10-14 02:21:40

标签: r loops dataframe datatable

我有一个包含idstartsendssame_person

列的数据表

same_person用于检查该行是否具有与之前相同的ID。

library(data.table)
id = c(1,1,2,2)
starts = c(0,5,0,9)
ends = c(5,10,9,20)
same_person = c(0,0,0,0)
df <- data.table(id, starts, ends, same_person)

df
      id starts ends same_person
# 1:  1      0    5           0
# 2:  1      5   10           0
# 3:  2      0    9           0
# 4:  2      9   20           0

预期产出为:

1.比较两个连续行的id如果它们相同,则将same_person替换为1.
2.对于同一个人,使starts等于第一行。

我使用2 for循环来实现它们。

首先,我检查前一行的id行,如果相同,则将same_person替换为1。

for (i in 2:nrow(df)){
    if(df$id[i] == df$id[i-1]){
        df$same_person[i] <- 1   
    }
   }

df
      id starts ends same_person
# 1:  1      0    5           0
# 2:  1      5   10           1
# 3:  2      0    9           0
# 4:  2      9   20           1

根据之前的结果,如果他们是同一个人,我会更改starts

for (i in 1:nrow(df)){
    if(df$same_person[i] == 1){
     df$starts[i] <- df$starts[i-1]    
    }
 }


df
      id starts ends same_person
# 1:  1      0    5           0
# 2:  1      0   10           1
# 3:  2      0    9           0
# 4:  2      0   20           1

由于此数据表是简化版本,因此不需要很长时间。但在我的实际工作中,需要花费很多时间。

我想知道我是否可以在不使用循环的情况下实现这两个步骤。

2 个答案:

答案 0 :(得分:0)

第一行找到重复项,然后下一行从starts中显示的第一个值替换data.frame的重复项。

   df$same_person <- 1 * duplicated(df$id)
    df$starts[which(df$same_person == 1)] <- 
      df$starts[which(df$same_person == 1) - 1]

答案 1 :(得分:0)

看看你的评论,似乎你想要做很多事情。在这种情况下,写一个循环可能会更好。

首先找到唯一的ID,然后处理它们。以下信息1只是same_person的最后一行,具有相同的id

unique_ids <- unique(df$id)
for (uid in unique_ids) {
  n_rows <- which(df$id == uid)
  if (length(n_rows) > 2)
  df$same_person[max(n_rows)] <- 1
}