我很难理解为什么我下面的代码只有在结合使用rowwiseifelse时才能工作.或者更准确地说,我想我明白了为什么它在那个场景中工作,但不明白为什么它不能简单地与if_else一起工作.

我要做的是,我要判断某一行是否包含单词"infle"或"outfile",以及它是否有相对路径("…").如果它有单词"infle/outfile"而不是相对路径,那么它有一个绝对路径"C:".在这种情况下,我想用其他名称替换用户名(这里是:"test").

有什么 idea 吗?

数据:

df <- structure(list(value = c("infile 'C:\\Users\\USER\\folder\\Data.sav'", 
"infile '..\\folder\\Data.sav'", "outfile '..\\folder\\Data.sav'", 
"test", "")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-5L))

user_name <- "test"

有效的代码:

df |> 
  rowwise() |> 
  mutate(value = ifelse(str_detect(value, "infile|outfile") & !str_detect(value, "\\'\\.\\.\\\\"),
                        str_replace(value,
                                    str_sub(value,
                                            str_locate_all(value, "\\\\")[[1]][2] + 1,
                                            str_locate_all(value, "\\\\")[[1]][3] - 1),
                                    user_name),
                        value)) |> 
  ungroup()

带输出:

# A tibble: 5 × 1
  value                                       
  <chr>                                       
1 "infile 'C:\\Users\\test\\folder\\Data.sav'"
2 "infile '..\\folder\\Data.sav'"             
3 "outfile '..\\folder\\Data.sav'"            
4 "test"                                      
5 ""   

不起作用的代码:

df |> 
  mutate(value = if_else(str_detect(value, "infile|outfile") & !str_detect(value, "\\'\\.\\.\\\\"),
                        str_replace(value,
                                    str_sub(value,
                                            str_locate_all(value, "\\\\")[[1]][2] + 1,
                                            str_locate_all(value, "\\\\")[[1]][3] - 1),
                                    user_name),
                        value))

我认为这是可行的,但也给出了一个警告:

Warning messages:
1: Problem while computing `value = if_else(...)`.
ℹ empty search patterns are not supported 
2: Problem while computing `value = if_else(...)`.
ℹ empty search patterns are not supported 

不起作用的代码:

df |> 
  rowwise() |>
  mutate(value = if_else(str_detect(value, "infile|outfile") & !str_detect(value, "\\'\\.\\.\\\\"),
                        str_replace(value,
                                    str_sub(value,
                                            str_locate_all(value, "\\\\")[[1]][2] + 1,
                                            str_locate_all(value, "\\\\")[[1]][3] - 1),
                                    user_name),
                        value)) |> 
  ungroup()

Error in `mutate()`:
! Problem while computing `value = if_else(...)`.
ℹ The error occurred in row 2.
Caused by error:
! Empty `pattern` not supported

推荐答案

基本上,问题是if_else()计算每行中的true和false输出,而ifelse()只计算使用true和false表达式的位置.

此外,如果不使用rowwise(),那么mutate在每次迭代时都会在df$value中传递整个字符串集,然后为每一行的字符串的开头和结尾返回相同的索引.

要进行调试,我建议将计算过程稍微打断一下:

df %>% rowwise() %>%
       mutate(n=length(value), slen=str_length(value),
              l1=str_locate_all(value,"\\\\")[[1]][2]+1,
              l2=str_locate_all(value,"\\\\")[[1]][3]-1, 
              ssub=str_sub(value, l1, l2), 
              detect=str_detect(value, "infile|outfile")& !str_detect(value,"\\'\\.\\.\\\\"), 
              vout=if_else(detect, ssub, user_name))
# A tibble: 5 × 8
# Rowwise: 
  value                                            n  slen    l1    l2 ssub   detect vout 
  <chr>                                        <int> <int> <dbl> <dbl> <chr>  <lgl>  <chr>
1 "infile 'C:\\Users\\USER\\folder\\Data.sav'"     1    38    18    21 "USER" TRUE   USER 
2 "infile '..\\folder\\Data.sav'"                  1    27    19    10 ""     FALSE  test 
3 "outfile '..\\folder\\Data.sav'"                 1    28    20    11 ""     FALSE  test 
4 "test"                                           1     4    NA    NA  NA    FALSE  test 
5 ""                                               1     0    NA    NA  NA    FALSE  test 

如果没有rowwise(),mutate会一次获取value列中的所有字符串,并在every single row上找到相同的剪切位置:

df %>% 
       mutate(n=length(value), slen=str_length(value),
              l1=str_locate_all(value,"\\\\")[[1]][2]+1,
              l2=str_locate_all(value,"\\\\")[[1]][3]-1, 
              ssub=str_sub(value, l1, l2), 
              detect=str_detect(value, "infile|outfile")& !str_detect(value,"\\'\\.\\.\\\\"), 
              vout=if_else(detect, ssub, user_name))
# A tibble: 5 × 8
  value                                            n  slen    l1    l2 ssub    detect vout 
  <chr>                                        <int> <int> <dbl> <dbl> <chr>   <lgl>  <chr>
1 "infile 'C:\\Users\\USER\\folder\\Data.sav'"     5    38    18    21 "USER"  TRUE   USER 
2 "infile '..\\folder\\Data.sav'"                  5    27    18    21 "\\Dat" FALSE  test 
3 "outfile '..\\folder\\Data.sav'"                 5    28    18    21 "r\\Da" FALSE  test 
4 "test"                                           5     4    18    21 ""      FALSE  test 
5 ""                                               5     0    18    21 ""      FALSE  test 

一旦你计算了错误的位置来子集你的字符串,我认为你很幸运if_else抛出了一个不同的错误.

R相关问答推荐

使用ggplot将平滑线添加到条形图

R创建一个数据透视表,计算多个组的百分比

gt()从gt为相同内容的单元格 colored颜色 不同?

为什么在ggplot2中添加geom_text这么慢?

如何在geom_col中反转条

在R中使用download. file().奇怪的URL?

传递ggplot2的变量作为函数参数—没有映射级别以正确填充美学

plotly hover文本/工具提示在shiny 中不起作用

如何将SAS数据集的列名和列标签同时包含在r中GT表的表首?

QY数据的处理:如何定义QY因素的水平

在R中,我如何使用滑动窗口计算位置,然后进行过滤?

如何根据R中其他变量的类别汇总值?

自定义gggraph,使geom_abline图层仅在沿x轴的特定范围内显示

正则表达式在第二个管道和第二个T之后拆分R中的列

创建列并对大型数据集中的特定条件进行成对比较的更高效程序

将具有坐标列表列的三角形转换为多个多边形

有没有办法一次粘贴所有列

在shiny 表格中输入的文本在第一次后未更新

将仪表板中的值框大小更改为Quarto

希望解析和复制R中特定模式的数据