繁体   English   中英

将一行与所有其他行进行比较

[英]Compare one row to all other rows

我在R中有以下数据框

  ID     bay    row    tier
  1       1      2      80
  2       3      2      80
  3       2      5      06
  4       4      5      06
  5       23     6      82
  6       25     6      82
  7       24     6      82
  8       4      12     08

我想要找到的是rowtier值相等,同时bay应该是一个odd ,两个相同的row and tier条目之间的bay差异应该是2

例如

 ID     bay    row    tier
 1       1      2      80
 2       3      2      80

上面的两行符合我的条件row and tier是相同的, bay是奇数, two bay数字之间的差异是2 ,我需要生成一个标志,将为两个行生成,让我们说1,2,3唯一标识对

我想要的数据帧是

 ID     bay    row    tier   flag
 1       1      2      80     1
 2       3      2      80     1
 3       2      5      06     NA
 4       4      5      06     NA
 5       23     6      82     2
 6       25     6      82     2
 7       24     6      82     NA
 8       4      12     08     NA

我怎么能在r?

您可以按如下方式获取子集,

ind <- duplicated(df[c('row', 'tier')]) & df$bay%%2 == 1|
       duplicated(df[c('row', 'tier')], fromLast = TRUE) & df$bay%%2 == 1
df1 <- df[ind,]
df1 <- df1[!!with(df1, ave(bay, new, FUN = function(i) c(TRUE, diff(i) == 2))),]
df1

这使

  ID bay row tier 1 1 1 2 80 2 2 3 2 80 5 5 23 6 82 6 6 25 6 82 

要获得旗帜,

df$flag <- cumsum(c(1, diff(which(ind)) != 1))[match(df$ID, df1$ID)]
df

这使,

 ID bay row tier flag 1 1 1 2 80 1 2 2 3 2 80 1 3 3 2 5 6 NA 4 4 4 5 6 NA 5 5 23 6 82 2 6 6 25 6 82 2 7 7 24 6 82 NA 8 8 4 12 8 NA 

使用tidyverse ,你可以尝试这样的事情:

df %>%
  group_by(row,tier) %>%
  mutate(flg = if_else(bay %%2 >0, 1, 0)) %>%
  filter(flg == 1) %>%
  mutate(df2 = lead(bay,1) - bay) %>%
  filter(df2 == 2) %>%
  select(-df2) %>%
  ungroup()%>%
  mutate(flg = 1:n()) %>%
  right_join(df) %>%
  mutate(flg = coalesce(flg,lag(flg,1)))

这使:

     ID   bay   row  tier   flg
  <int> <int> <int> <int> <int>
1     1     1     2    80     1
2     2     3     2    80     1
3     3     2     5     6    NA
4     4     4     5     6    NA
5     5    23     6    82     2
6     6    25     6    82     2
7     7    24     6    82    NA
8     8     4    12     8    NA

我们可以用

library(data.table)
i1 <- setDT(df1)[, .I[all(bay%%2 == 1) & diff(bay)==2], .(grp = rleid(bay%%2),row, tier)]$V1
df1[i1, flag := 1
  ][!is.na(flag), flag := as.numeric(.GRP), .(row, tier)]
df1
#    ID bay row tier flag
#1:  1   1   2   80    1
#2:  2   3   2   80    1
#3:  3   2   5    6   NA
#4:  4   4   5    6   NA
#5:  5  23   6   82    2
#6:  6  25   6   82    2
#7:  7  24   6   82   NA
#8:  8   4  12    8   NA

一种不同的方法。 你提到你只需要一个唯一的标识符。 如果数字不必是连续的,可以这样实现:

library(dplyr)
df$flag=NA
group = df %>% group_indices(row,tier)
idx = which(df$bay %% 2==1 & (df$bay - lag(df$bay,default=-1)==2 | group != lag(group,default=-1)))
df$flag[idx]=group[idx]

输出:

  ID bay row tier flag
1  1   1   2   80    1
2  2   3   2   80    1
3  3   2   5    6   NA
4  4   4   5    6   NA
5  5  23   6   82    3
6  6  25   6   82    3
7  7  24   6   82   NA
8  8   4  12    8   NA

希望这可以帮助!

我写了这个蹩脚的循环,但它的工作原理

df$flag = NA

for(i in 1:nrow(df)) {
  for(j in 2:nrow(df)) {
    if(df$row[i] == df$row[j]){
      if(df$tier[i] == df$tier[j]){
        if(df$bay[i] %% 2 != 0){
          if(df$bay[j] %% 2 != 0){
            if(abs(df$bay[i] - df$bay[j]) == 2){
              df$flag[i] = i
              df$flag[j] = i
         }
       }

      }
    }
   }
  }
 }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM