【问题标题】:Using seq_along() to handle Date in for loop使用 seq_along() 处理 for 循环中的日期
【发布时间】:2017-03-26 19:53:22
【问题描述】:

这里有两个dfs 示例数据:

df1

ID      First.seen  Last.seen 
A10   2015-09-07  2015-09-16       
A11   2015-09-07  2015-09-19 



df2
 ID      First_seen  Last_seen
 A1      2015-09-07  0
A10      2015-09-07  0

如果ID 在两个dfs 中通用,我想填写df2$Last_seen。请注意,在实际数据中,我在两个 dfs 中都有多个 ID。我试过 for 循环,但我只得到数值:

for (i in 1:nrow(df2)){
  if (df2$ID[i] %in% df1$ID) {
    df2$Last_seen[i] <- df1$Last.seen[df1$ID == df2$ID[i]]
  }else{
    df2$Last_seen[i] <- 0
  }
}

我找到了this 对使用seq_along 的同一问题的回答,但是当我应用此代码时,我得到了df1$Last_seen[i] == 1 的结果:

 for (i in seq_along(1:nrow(df2))){
      if (df2$ID[i] %in% df1$ID) {
        df2$Last_seen[i] <- df1$Last.seen[df1$ID == df2$ID[i]]
      }else{
        df2$Last_seen[i] <- 0
      }
    }

有什么正确使用方法的建议吗?

【问题讨论】:

    标签: r date for-loop numeric


    【解决方案1】:

    您不需要循环来执行此操作。您需要在 ID 上加入表格。这可以通过dplyr 完成:

    df1 <- read.table(text="ID      First.seen  Last.seen
    A10   2015-09-07  2015-09-16
    A11   2015-09-07  2015-09-19",header=TRUE, stringsAsFactors=FALSE)
    
    df2<- read.table(text="ID      First_seen  Last_seen
     A1      2015-09-07  0
    A10      2015-09-07  0",header=TRUE, stringsAsFactors=FALSE)
    
    library(dplyr)
    left_join(df2,df1)
       ID First_seen Last_seen First.seen  Last.seen
    1  A1 2015-09-07         0       <NA>       <NA>
    2 A10 2015-09-07         0 2015-09-07 2015-09-16
    

    如果你想要一个三列表格:

    left_join(df2,df1, by=c("ID" = "ID","First_seen"="First.seen")) %>%
    mutate(Last_seen=ifelse(is.na(Last.seen),Last_seen,Last.seen)) %>%
    select(-Last.seen)
    
       ID First_seen  Last_seen
    1  A1 2015-09-07          0
    2 A10 2015-09-07 2015-09-16
    

    编辑要更改 Last_seen 为 0 的出现次数,您可以添加另一个 ifelse

    left_join(df2,df1, by=c("ID" = "ID","First_seen"="First.seen")) %>%
    mutate(Last_seen=ifelse(is.na(Last.seen),Last_seen,Last.seen),
           Last_seen=ifelse(Last_seen==0,format(as.Date(First_seen)+16,"%Y-%m-%d"),Last.seen))%>%
    select(-Last.seen)
    
       ID First_seen  Last_seen
    1  A1 2015-09-07 2015-09-23
    2 A10 2015-09-07 2015-09-16
    

    EDIT2

    left_join(df2,df1, by=c("ID" = "ID","First_seen"="First.seen")) %>%
    mutate(Last_seen=ifelse(is.na(Last.seen),Last_seen,Last.seen),
           Last_seen=ifelse(Last_seen==0,format(as.Date(First_seen)+16,"%Y-%m-%d",origin = "1900-01-01"),Last.seen))%>%
    select(-Last.seen)
    
       ID First_seen  Last_seen
    1  A1 2015-09-07 2015-09-23
    2 A10 2015-09-07 2015-09-16
    

    【讨论】:

    • 太棒了,很有道理。如果我想将生成的dfLast_seen 列中的0 值更改为First_seen + 16 days 的值
    • 我刚刚使用我的完整数据测试了“三列表”解决方案,我再次得到数值而不是日期。有什么想法吗?
    • @Bonono 如果您使用 left_join... 创建的对象是 df1,请在所有操作之后执行此操作:df1$Last_seen &lt;- as.Date(df1$Last_seen,format("%Y-%m-%d"))
    • 我上次遇到了这个问题 - 它只是将数值转换为NAs
    • 是的,就是这样。请参阅我的第二次编辑。我只是保持一切的性格。如果需要,您可以稍后将其更改为日期。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-01
    • 2022-12-04
    • 1970-01-01
    相关资源
    最近更新 更多