使用R将字符值更改为负数

j2datikz  于 2022-12-27  发布在  其他
关注(0)|答案(2)|浏览(234)

我有下面的 Dataframe 。所有的列都是字符列,但除了第一列,其余的列都包含数值:

df <- data.frame(col1=c('', 'assets', 'loss', 'liability'),
                 col2=c("", "5,000", "(1,400)", "300"),
                 col3=c("", "4,500", "(1,100)", "500"))

df

col1       col2      col3
<chr>      <chr>    <chr>
        
assets     5,000    4,500
loss      (1,400)  (1,100)
liability   300      500 
                                                                  ​               ​        ​

任务是--如果一个值在()范围内[例如,loss值],我需要将该值设为负数。
我正在尝试以下脚本:

clean_columns <- function(dataframe){

  dataframe_new <- copy(dataframe)

  for (idx in 2:length(names(dataframe))) {
      
      # Check if text contains -- ( )
      if (grepl(is.na(dataframe_new[, idx]), "(", fixed = TRUE)) {
        
      # Remove characters -- () , -- and multiply -1
      dataframe_new[, idx] <- gsub("[(,)]", "", dataframe_new[, idx]) %>%
        as.numeric(dataframe_new[, idx])*(-1)
      
      } else 
      # Remove characters -- ,
      dataframe_new[, idx] <- gsub("[,]", "", dataframe_new[, idx]) %>%
        as.numeric(dataframe_new[, idx])
} 
  return(dataframe_new)
}

该函数正确删除字符,但使loss值为NA。

clean_columns(df)

col1       col2     col3
<chr>      <dbl>    <dbl>
            NA       NA
assets     5000     4500
loss        NA       NA
liability  300      500

所需输出

col1       col2     col3
<chr>      <dbl>    <dbl>
            NA       NA
assets     5000     4500
loss      -1400    -1100
liability   300      500

如有任何建议,将不胜感激。谢谢!

dbf7pr2w

dbf7pr2w1#

我们循环across至少有一些数字的列,删除),用-替换(,并用parse_number解析它

library(dplyr)
library(stringr)
 df %>% 
  mutate(across(-1, 
   ~ readr::parse_number(str_replace(str_remove(.x, "\\)"), fixed("("), "-") )))
  • 输出
col1  col2  col3
1              NA    NA
2    assets  5000  4500
3      loss -1400 -1100
4 liability   300   500

或者,我们可以检测(乘以-1,而不是删除(

df %>%
   mutate(across(-1, ~ c(1, -1)[1 + str_detect(.x, fixed("("))] * 
         readr::parse_number(.x) ))
6kkfgxo0

6kkfgxo02#

下面是一个没有我最喜欢的函数parse_number()的示例:

library(dplyr)
library(stringr)

df %>% 
  mutate(across(-col1, ~str_replace_all(., "[[:punct:]]", ""))) %>% 
  type.convert(as.is = TRUE) %>% 
  mutate(across(-col1, ~ifelse(col1 == "loss", .*-1, .))) %>% 
  as_tibble()
col1         col2  col3
  <chr>       <dbl> <dbl>
1 ""             NA    NA
2 "assets"     5000  4500
3 "loss"      -1400 -1100
4 "liability"   300   500

相关问题