我在一个非常大的小标题“ 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”中的项目,但这只是巧合。
答案 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