Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 将一行与所有其他行进行比较_R - Fatal编程技术网

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

R 将一行与所有其他行进行比较,r,R,我在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

我在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
我想找到的是
值相等,同时
间隔
应该是一个
奇数
数,两个相同的
行和层
条目之间的间隔差应该是
2

例如

以上两行限定了我的条件
行和层与
间隔
相同,为奇数,
两个间隔
之间的差值为
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中完成它?

我们可以使用

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
库(data.table)

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

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]
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 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

希望这有帮助

我写了这个蹩脚的for循环,但它很有效

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
         }
       }

      }
    }
   }
  }
 }

使用
tidyverse
,您可以尝试以下操作:

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]
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
ID间隔行层flg
1     1     1     2    80     1
2     2     3     2    80     1
3 3 2 5 6 NA
4 4 5 6 NA
5     5    23     6    82     2
6     6    25     6    82     2
7724682NA
884128NA

您可以按如下方式获得子集

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
为了拿到国旗

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

如果将
ID
编号7的
bay
更改为27,则第二种方法将失败。您没有检查2
差异条件。实际上,您的两种方法都无法满足该条件。@Florian我们如何在dplyr方法中添加2
差异条件?@Florian
dplyr
方法很简单。如果我们可以在约定的条件中添加2的差异,那么可以很容易地使用lag()检查差异。我会看看我是否能做到这一点。你想如何处理一组中连续3行满足条件的情况?向上投票,因为似乎是唯一一个彻底阅读了问题的人,而不是像我一样试图复制预期的输出。老实说,这就是我喜欢
%%>%%
操作符的原因。@Aramis7d介意删除您的评论吗?这个问题已经解决了。谢谢
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