【问题标题】:R - Compare values in two columns in different rowsR - 比较不同行中两列的值
【发布时间】:2017-08-09 03:51:57
【问题描述】:

我有一个数据框df,如下所示,它有两个特征,一个出发城市和一个到达城市。每两行存储关于去程和回程航班的信息。

  Departure Arrival
1    A          B
2    B          A
3    F          G
4    G          F
5    U          V
6    V          U
7    K          L
8    K          L

在最后两行中可以看到,重复同一航班的数据存在一些不一致。

如何每两行比较第一行的出发城市和第二行的到达城市,并保持相等的。 数据集非常大,当然不考虑使用 for 循环。

提前谢谢你。

【问题讨论】:

  • 在第 7 行和第 8 行有连续两排航班的情况下,您是在第 9 行实际返回,还是直接去另一个航班?跨度>
  • 我在下面发布了几个选项,但我想说你会因为发布一些非常适合谷歌的东西而被撕毁。在 20803 其他人说之前,先尝试搜索。
  • 它去了另一个航班。谢谢

标签: r


【解决方案1】:

这是一种使用headtail 比较行对以将它们对齐的方法。

# find Departures that match the Arrival in the next row
sames <- which(head(dat$Departure, -1) == tail(dat$Arrival, -1))
# keep pairs of rows that match, maintaining order with `sort`
dat[sort(unique(c(sames, (sames + 1)))),]
  Departure Arrival
1         A       B
2         B       A
3         F       G
4         G       F
5         U       V
6         V       U

请注意,这两个变量必须是字符向量,而不是因子变量。如有必要,您可以使用as.character 强制他们使用字符。

数据

dat <-
structure(list(Departure = c("A", "B", "F", "G", "U", "V", "K", 
"K"), Arrival = c("B", "A", "G", "F", "V", "U", "L", "L")), .Names = c("Departure", 
"Arrival"), class = "data.frame", row.names = c("1", "2", "3", 
"4", "5", "6", "7", "8"))

【讨论】:

  • 这非常有效,除非有重复的行后面跟着与前一个 Arrival 具有相同 Departure 的行,例如 dat2=rbind(dat,c("L","K"),c("K","P"))dat3=rbind(dat,c("L","T"),c("T","P")),然后它会删除错误的行。
  • 鉴于提供的数据,返回的值将是相同的(行名除外)。如果其他列可用,则可以在组级操作中使用这些列来区分它们。
【解决方案2】:

所以您只想要独特的飞行路径?有很多方法可以做到这一点,我认为最快的方法是使用 data.table,例如:

 library(data.table)
 df <- as.data.table(df)

 uniqueDf <- unique(df)

你也可以使用复制功能,比如

 df <- df[!duplicated(df), ]

应该做得很好。

【讨论】:

  • 如果您想删除重复的行,这很有效,但我认为顺序在这里很重要。如果有两组来自同一地点和目的地的航班怎么办?这将删除除第一对之外的所有内容。
  • @Eumenedies fair,阅读整篇文章的方式!实际上,从方法的角度来看,我建议这个人误读了什么是真正独特的航班,因为重复的航班包含任何其他识别信息。在不确定它们是否相同的情况下,我会犹豫是否要删除它们....
【解决方案3】:

你也可以这样做:

right = rep(df[c(T,F),"Arrival"]==df[c(F,T),"Departure"],each=2)
df[right,]

这会返回:

   Departure Arrival
1          A       B
2          B       A
3          F       G
4          G       F
5          U       V
6          V       U

【讨论】:

    【解决方案4】:

    此答案不查找唯一记录,它专门检查某行是否与之前的行重复。

    如果该行重复,则添加一个带有 1 的新列:

     for(i in 2:length(df$Departure)){df$test[i]=ifelse(df$Departure[i] == df$Departure[i-1] & df$Arrival[i] == df$Arrival[i-1], 1,0)}
    

    虽然循环可能很慢:

    library(data.table)

    df$test2 = ifelse(df$Departure == shift(df$Departure) & df$Arrival == shift(df$Arrival), 1,0)
    

    【讨论】:

      【解决方案5】:

      如果对您有用,请尝试以下解决方案:

      df[duplicated(paste0(df$Departure,df$Arrival))==F,]
      

      【讨论】:

      • 这是对我的一个很好的补充,因为它说明了如何通过重复列来做到这一点。我会说虽然只有两个......
      猜你喜欢
      • 2014-01-06
      • 2018-04-02
      • 1970-01-01
      • 2015-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多