R: 错误在哪里:if 语句覆盖多列

R: Where is the mistake: if statement over multiple columns

我有以下数据 table,列为 class "character"

dt <- data.table(V1 = c("0", "1", "1/2", "4"), V2 = c("1/2", "3/4", "", ""))

我想在第二列和第一列中只包含自然数的所有分数。我提出了以下解决方案:

if(str_detect(new$V1, "/")){
  new$V2 <- new$V1
  new$V1 <- 0
}

并且还尝试将其嵌入到一个函数中并用 sapply.

完成它
FractionExtraction <- function(x, y) {
  if(str_detect(x, "/")){
  y <- x 
  } else {y <- y}
  y
}

dt$V2  <- sapply(dt$V1, FractionExtraction, dt$V2)

我也尝试在 if 语句中使用 %in%,或者将“<-”替换为等号,但我仍然会收到以下错误

Warning message:
In if (str_detect(new$V1, "/")) { :
  the condition has length > 1 and only the first element will be used

理想情况下,输出如下所示:

> dt
   V1  V2
1:  0 1/2
2:  1 3/4
3:  0 1/2
4:  4    

任何帮助将不胜感激!!

dplyr:

dt %>% 
  mutate(V2 = ifelse(str_detect(V1, "/"), V1, V2),
         V1 = ifelse(str_detect(V1, "/"), 0, V1))
  V1  V2
1  0 1/2
2  1 3/4
3  0 1/2
4  4    

我们可以只在 i 中指定条件并将 'V2' 和 'V1' 列的值分配 (:=) 到 'V1' 和 0

library(data.table)
library(stringr)
dt[str_detect(V1, "/"), c('V2', 'V1') := .(V1, 0)]
dt
#   V1  V2
#1:  0 1/2
#2:  1 3/4
#3:  0 1/2
#4:  4    

在 OP 中。代码,它正在执行 if/else 未矢量化并且 OP 通过遍历 'V1' 进行修正,而 'y' 仍然是 sapply 中的整列,结果在 'V1' 的每个元素中获取 4 个值。相反它可以是Map,但是代码也需要一些改变


基准

dt1 <- dt[rep(seq_len(.N), 1e7)]
system.time(dt1 %>%  mutate(V2 = ifelse(str_detect(V1, "/"), V1, V2),
          V1 = ifelse(str_detect(V1, "/"), 0, V1)))
#   user  system elapsed 
# 30.485   2.966  33.506 
system.time(dt1[str_detect(V1, "/"), c('V2', 'V1') := .(V1, 0)])
#   user  system elapsed 
#  5.143   0.689   5.811