删除 r DataFrame 中多个已定义列中的特定字符和特殊字符

Removing specific and special characters in multiple defined columns in r dataframe

提问人:Andrea 提问时间:9/24/2023 最后编辑:Andrea 更新时间:9/24/2023 访问量:26

问:

如何删除r数据帧中多个已定义列中的特定字符和特殊字符?

我有一个数据集,需要一些认真的清理,类似于下面的示例数据。我的最终目标是建立一个数据帧,其中列类型与列名匹配(例如,date = date,times = time,numeric1 = numeric,char = character),并且其中删除了所有特殊字符或值,否则会阻止转换为正确的类型。真实的数据集包含 60 多个列,其中大约一半需要删除多个字符,因此我想找到一种方法来选择合适的列以尽可能少的代码重复进行多次修改。

请参阅下面的示例数据输入和所需输出。根据要求,此图像显示了所需的输出数据帧外观。

任何帮助将不胜感激。

#Example Data Input from nested list
my_nested_list <- list(date=c('8/16/2010', '8/17/2010', '8/18/201', '8/19/2010', '8/20/2010'),
                       times=c('8:45', '14:20', '13:00', '15:20', '9:05'),
                       numeric1=c('>3.0','> 3.0','1.2m','.8','?1.8'),
                       character1=c('Epi', '', 'Hypo', 'Epi', ''),
                       character2=c('GC1238', '', 'GC1239', '', 'GC1240'),
                       numeric2=c('N/A', '-', '8.9', '', '2.2'),
                       numeric3=c('R', '12.4', '4.1', '', '11.58'))

#Convert nested list to the dataframe by columns
df <- as.data.frame(do.call(cbind, my_nested_list))
df
sapply(df, class) #displays all column types as characters

我知道您可以使用 str_replace_all() 或 gsub() 替换一列或所有列中的特殊字符,但我想在指定的列中这样做(例如,df$numeric1、df$numeric2、df$numeric3 或 df[3]、df[5:6])。与示例数据一样,我也有非特殊字符,只需要从数字列中删除(例如,“R”、“>”、“>”、“m”、“-”、“N/A”)

这就是我更换特殊字符和每个单独字符的方式,一次一列,但我对想法持开放态度。我也尝试过做多列,但它不起作用。

#One column at a time
##Using str_replace_all() in one specified column 
df$numeric1 <- str_replace_all(df$numeric1, "\[\[:punct:\]\]", " ")
df$numeric1 <- str_replace_all(df$numeric1, ""R", " ")

##Using base gsub() in one specified column
gsub("\[\[:punct:\]\]", " ", df$numeric1)
gsub("R", " ", df$numeric1)

#One character in multiple columns with resulting error: "Error in `[.default`(df, cols_nan) : invalid subscript type 'list'"
cols_nan <- c(df[5:6])
df[cols_nan] <- gsub('[^[:alnum:] ]','',df[cols_nan]) 

我尝试了几种方法来更改日期和时间列类型(根据以前的 stackoverflow 帖子)。当他们更改列类型时,他们不会在列中返回任何值。

#dates
df$date <- lubridate::mdy(df$date)
df$date <- as.Date(df$date, format= %Y-%m-%d")
df$date <- lubridate::mdy(df$date)

#time
df[['times']] <- strptime(df[['times']], format = "%H:%M:%S")

一次修改一个字符和一列时,列类型将使用以下命令进行更改。

df <-data.frame(df,  stringsAsFactors=FALSE)
sapply(df, class) #I would like to display all column types as designated in headers
r 日期时间 gsub

评论

0赞 Andre Wildberg 9/24/2023
“my_nested_list”中的“char”包含 6 个值。否则就足够了。另外,您能否通过编辑添加预期的输出应该是什么样子?data.frame(my_nested_list)
0赞 Mark 9/24/2023
嗨,安德里亚!欢迎来到 StackOverflow。预期输出有 5 行,但示例 df 有 6 行。额外的一行去哪里?

答:

0赞 Mark 9/24/2023 #1

似乎你想要这样的东西:

pacman::p_load(tidyverse, hms)

df |> mutate(across(starts_with("num"), parse_number), 
             across(starts_with("times"), parse_hm),
             across(starts_with("date"), ~ as.Date(.x, "%m/%d/%Y")),
             across(starts_with("char"), ~ ifelse(.x == "", NA_character_, .x)))

输出:

# A tibble: 6 × 6
  date       times  numeric1 char  numeric2 numeric3
  <date>     <time>    <dbl> <chr>    <dbl>    <dbl>
1 2010-08-16 08:45       3   Epi       NA       NA  
2 2010-08-17 14:20       3   NA        NA       12.4
3 0201-08-18 13:00       1.2 Hypo       8.9      4.1
4 2010-08-19 15:20       0.8 Epi       NA       NA  
5 2010-08-20 09:05       1.8 NA         2.2     11.6
6 2010-08-16 08:45       3   NA        NA       NA  

笔记:

  1. 我用于 DataFrame 中的每个列类型,假设在较大的 DataFrame 中,对于示例 DataFrame 中只有一列的列,将有多个列。此外,如果列的名称与示例中的名称不一致,则可以使用不同的方法来选择列 - 有很多方法,无法在此处列出,但您可以就真实数据征求我的建议,或查看文档。across()
  2. cols_nan <- c(df[5:6])获取 DataFrame 中实际的第五列和第六列。然后,您尝试根据列为数据帧编制索引,但该列会失败,因为该列是列表。你可能想要(但即使这样也会产生一个卡顿的结果)。gsub('[^[:alnum:] ]','',df[5:6])
  3. 我给出的输出的一个问题是第三个日期的年份值。我保持它不变,因为 a. 它对你来说很容易修复,但 b. 因为我不想创建一个对那个行有效的修复,但对真实数据集中的许多其他行不起作用(甚至破坏东西)。如果您提供更多错误日期行的示例,那么我将能够提供更多帮助。
  4. re:- 事情需要在 R- 的正则表达式中转义两次,即它应该是"\[\[:punct:\]\]""\\[\\[:punct:\\]\\]"