【问题标题】:select elements within a loop R在循环 R 中选择元素
【发布时间】:2017-07-12 16:56:56
【问题描述】:

我尝试在论坛中搜索此问题的答案,但找不到。 我想滚动数据框列 (IN_FID) 的唯一值,并将与该值关联的另一列 (NEAR_FID) 中的值(可能有一个或多个)添加到列表中。然后将 IN_FID 添加到列表中。如果在此过程中之前已经看到 NEAR_FID 中的值,则不会将 IN_FID 添加到列表中。我知道我没有将它包含在代码中,但理想情况下,我还想随机而不是按顺序循环遍历 IN_FID 值。 我在这段代码中做错了什么?

eagle
   IN_FID NEAR_FID
1       2        1
2       2        2
3       2        3
4       8        4
5       9        2
6       9        7
7       9        8
8       9        9
9      16        2
10     16       11
11     21       12

p.good = list()
p.bad = list()
INFIDS = unique(eagle$IN_FID)
NEARFIDS = unique(eagle$NEAR_FID)
t.used = NEARFIDS

for (i in INFIDS) {
sub = eagle[eagle$IN_FID == i, ]
x = sub$NEAR_FID
if (all(x) %in% t.used){
    p.good = c(p.good, i)
    t.used[t.used != all(x)]

} else { 
    p.bad = c(p.bad, i)
}

期望的输出是:

p.good
[1] 2 8 21  (because NEAR_FID of 2 is present in 9 and 16)
p.bad
[1] 9 16
t.used
= empty because it will have used the values during the loop

【问题讨论】:

  • 您阅读过all() 的文档吗?可能还有其他问题,但那个问题对我来说很突出。
  • 您能否为此输入提供所需的输出,以便测试可能的解决方案?
  • 我认为这与 x 大小不同并且当 x 包含多个值时不会从 t.used 中删除 x 的事实有关
  • 不要检查all(x) 是否在t.used 中。检查all(x %in% t.used)(如果这就是你想要做的——我仍然对你的过程很困惑)。

标签: r list for-loop


【解决方案1】:

你可以使用函数duplicated()

index_dup = which(duplicated(eagle$NEAR_FID))

p.bad = unique(eagle$IN_FID[index_dup])

index_bad = c()
for (i in p.bad){
  index_bad = c(index_bad,which(eagle$IN_FID == i))
}

p.good = unique(eagle$IN_FID[-index_bad])

对于随机化,您可以随机排列数据的行顺序,然后再次应用上面的代码

eagle_random <- eagle[sample(1:nrow(eagle)), ]

【讨论】:

    【解决方案2】:

    声明为vector,而不是列表:

    p.good = NULL
    p.bad = NULL
    
    INFIDS = unique(eagle$IN_FID)
    NEARFIDS = unique(eagle$NEAR_FID)
    t.used = NEARFIDS
    

    不是min:max,而是遍历向量for (i in INFIDS)的元素:

    for (i in INFIDS) {
         x = (eagle %>% filter(IN_FID == i))$NEAR_FID   # combine into single statement
         if (all(x %in% t.used)) {    # was all(x) %in% t.used before
            p.good = c(p.good, i)
            t.used = t.used[!(t.used %in% x)]  # was t.used != all(x)
        } else {
            p.bad = c(p.bad, i)  
        }
    }
    

    输出:

    p.good
    [1] 2  8 21
    
    p.bad
    [1] 9 16
    
    t.used
    [1] 7  8  9 11    # some values were not eliminated as you expected
    

    ----随机抽样----

    更改for (i in INFIDS)

    for (i in sample(INFIDS))。使用set.seed(1)控制随机抽样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-03
      • 1970-01-01
      • 2018-08-03
      • 1970-01-01
      • 1970-01-01
      • 2011-09-27
      • 2016-06-10
      • 2014-06-06
      相关资源
      最近更新 更多