%in%在控制台工作,但不在脚本中工作

时间:2018-08-04 00:09:30

标签: r console

我在一个非常大的小标题“ dt”中具有以下数据:

pr1   pr2  pr3  att_id
736  7569  7534 MD029374E
741    NA    NA MD020067E
741  7534    NA MD025172E
741  6639    NA MD045509E
736  7532    NA MD023417E
736  7309  7534 MD026105E
741  7534    NA MD028400L
736  7534    NA MD034753E

这段代码:

sections = c(740, 741, 742, 744)
i = 1
cx_col = 5

for (i in 1:nrow(dt)) {
        k = 1
        for (k in 1:3) {
            dt[i, cx_col] <- (dt[i, k] %in% sections)
        }
}

产生以下(错误)输出:

pr1   pr2  pr3  att_id    cx
736  7569  7534 MD029374E FALSE
741    NA    NA MD020067E FALSE
741  7534    NA MD025172E FALSE
741  6639    NA MD045509E FALSE
736  7532    NA MD023417E FALSE
736  7309  7534 MD026105E FALSE
741  7534    NA MD028400L FALSE
736  7534    NA MD034753E FALSE

它应该像这样:

pr1   pr2  pr3  att_id    cx
736  7569  7534 MD029374E FALSE
741    NA    NA MD020067E TRUE
741  7534    NA MD025172E TRUE
741  6639    NA MD045509E TRUE
736  7532    NA MD023417E FALSE
736  7309  7534 MD026105E FALSE
741  7534    NA MD028400L TRUE
736  7534    NA MD034753E FALSE

但是,如果我在控制台上逐行键入完全相同的代码,则数据文件将以我想要的方式结束。

为什么我的代码不能像在控制台上那样在脚本中执行?

请注意,我提供的样本数据没有pr2或pr3中“ sections”中的项目,但这只是巧合。

3 个答案:

答案 0 :(得分:4)

尝试

dt$cx <- apply(dt[,1:3], 1, function(row) any(row %in% sections) )
dt
  pr1  pr2  pr3    att_id    cx
1 736 7569 7534 MD029374E FALSE
2 741   NA   NA MD020067E  TRUE
3 741 7534   NA MD025172E  TRUE
4 741 6639   NA MD045509E  TRUE
5 736 7532   NA MD023417E FALSE
6 736 7309 7534 MD026105E FALSE
7 741 7534   NA MD028400L  TRUE
8 736 7534   NA MD034753E FALSE

编辑:如果您想更好地理解编码错误,则可以通过以下方式编写代码:

dt[,5] <- FALSE # instantiate the column and populate with FALSE
for (i in 1:nrow(dt)) {
  k = 1
  for (k in 1:3) {
    dt[i, 5] <- ((dt[i, k] %in% sections) | dt[i, 5]) 
# notice the additional OR dt[i,cx_col] construct here.
# This makes sure that previous "TRUE"s do not get overwritten.
  }
}

但是,从这里的许多答案中应该清楚的是,您不会用R编写这样的代码。(如果是Python,我们会说您的代码不是Pythonic;也许我应该说它不是非常Rtistic )

答案 1 :(得分:3)

我怀疑还有更多您没有告诉我们。问题不是%in%是不是不是$pr1的{​​{1}}中找到数字,而是在那里找到它,如图所示通过:

sections

请注意,我只是在第一列上进行迭代(愚蠢的是为此有一个for (i in 1:nrow(dt)) { for (k in 1:1) { # only looking at the first column here dt[i, cx_col] <- (dt[i, k] %in% sections) } } dt # pr1 pr2 pr3 att_id V5 # 1 736 7569 7534 MD029374E FALSE # 2 741 NA NA MD020067E TRUE # 3 741 7534 NA MD025172E TRUE # 4 741 6639 NA MD045509E TRUE # 5 736 7532 NA MD023417E FALSE # 6 736 7309 7534 MD026105E FALSE # 7 741 7534 NA MD028400L TRUE # 8 736 7534 NA MD034753E FALSE 循环,但是我保留了格式供参考)。

但是,您每次比较时都将for的值覆盖 ,因此,由于首先检查了df[i,xc_col],因此将k=1设置为{{1 }},但是当dt[*,5](目前关心2)时,它会被TRUE覆盖。

如果您要查找前三列中的任何一列(大的“或”行),则类似的方法将起作用。顺便说一句:不需要循环。

k=3

答案 2 :(得分:3)

我不确定在逐行运行时您在做什么,但是您正在做的 SOMETHING 有所不同。

对于每一行,请执行以下操作:

for (k in 1:3) {
    dt[i, cx_col] <- (dt[i, k] %in% sections)
  }

这将循环遍历第i行的前三列,并查看它是否位于sections中。您的第二和第三列似乎从未出现在sections中……我认为这不是您想要的。我猜你想要这样的东西:

dt <- tibble::tribble(~pr1 ,  ~pr2,  ~pr3  ,~att_id,
             736,  7569,  7534 ,"MD029374E",
             741,NA,NA,"MD020067E",
             741,  7534,NA,"MD025172E",
             741,  6639,NA,"MD045509E",
             736,  7532,NA,"MD023417E",
             736,  7309,  7534 ,"MD026105E",
             741,  7534,NA,"MD028400L",
             736,  7534,NA,"MD034753E")

sections = c(740, 741, 742, 744)
i = 1
cx_col = 5

for (i in 1:nrow(dt)) {
  ## notice I removed the second loop over each column
  dt[i, cx_col] <- (dt[i, 1] %in% sections)
}

dt
#> # A tibble: 8 x 5
#>     pr1   pr2   pr3 att_id    V5   
#>   <dbl> <dbl> <dbl> <chr>     <lgl>
#> 1   736  7569  7534 MD029374E FALSE
#> 2   741    NA    NA MD020067E TRUE 
#> 3   741  7534    NA MD025172E TRUE 
#> 4   741  6639    NA MD045509E TRUE 
#> 5   736  7532    NA MD023417E FALSE
#> 6   736  7309  7534 MD026105E FALSE
#> 7   741  7534    NA MD028400L TRUE 
#> 8   736  7534    NA MD034753E FALSE

如果您想在dplyr数据管道中执行此操作,则它将类似于以下内容:

dt %>%
  mutate(cx_col = case_when(pr1 %in% sections ~ TRUE, 
                            TRUE ~ FALSE)) ->
  output_df
output_df
#> # A tibble: 8 x 5
#>     pr1   pr2   pr3 att_id    cx_col
#>   <dbl> <dbl> <dbl> <chr>     <lgl> 
#> 1   736  7569  7534 MD029374E FALSE 
#> 2   741    NA    NA MD020067E TRUE  
#> 3   741  7534    NA MD025172E TRUE  
#> 4   741  6639    NA MD045509E TRUE  
#> 5   736  7532    NA MD023417E FALSE 
#> 6   736  7309  7534 MD026105E FALSE 
#> 7   741  7534    NA MD028400L TRUE  
#> 8   736  7534    NA MD034753E FALSE