【问题标题】:In data table, Compare rows and make calculations without loop in R在数据表中,比较行并在 R 中进行无循环计算
【发布时间】:2018-03-26 04:44:54
【问题描述】:

我有一个包含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

由于这个数据表是简化版,所以用不了多久。但在我的实际工作中,这需要很多。

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

【问题讨论】:

  • 预期输出是什么
  • 预期输出为:1.比较连续两行的id,如果相同,将same_person替换为1。2.对于同一个人,使开始时间相等到第一行。

标签: r loops dataframe datatable


【解决方案1】:

第一行查找重复项,然后下一行从data.frame 中出现的第一个值替换starts 的重复项。

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

【讨论】:

  • 谢谢。如果相同的id 出现两次以上,我只需要每个 id 的最后一行中的same_person 变为 1。
  • 如果我想比较两列怎么办。例如,没有id 列,如果第二行的starts 等于第一行的ends 时间。他们是same_person
  • 如果您对ids 进行了排序,那么您将在每个副本中得到1
【解决方案2】:

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

首先找到唯一ID,然后处理它们。以下 puts 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
}

【讨论】:

    猜你喜欢
    • 2012-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-15
    • 1970-01-01
    相关资源
    最近更新 更多