根据 R 中的特定列名从字符向量中删除逗号

Posted

技术标签:

【中文标题】根据 R 中的特定列名从字符向量中删除逗号【英文标题】:Remove commas from character vectors based on specific column names in R 【发布时间】:2017-10-17 10:03:27 【问题描述】:

我有一个大数据框。一个较小的子集如下:

structure(list(Date = c("2017-08-12", "2017-08-12", "2017-08-12"
  ), `Time (sec)` = c("19:01:04", "07:30:18", "04:29:38"), `4+DURATION` = c("26", 
  "58,000", "27"), `4+'000 (AVG)` = c("0.0000", "0.0000", "0.0000"), 
  `15+DURATION` = c("26", "57,000", "27"), `15+'000 (AVG)` = c("0.0000", 
  "0.0000", "0.0000")), .Names = c("Date", "Time (sec)", "4+DURATION", 
   "4+'000 (AVG)", "15+DURATION", "15+'000 (AVG)"), row.names = 3:5, class = "data.frame")

实际的数据框是这样的:

       Date Time (sec) 4+DURATION 4+'000 (AVG) 15+DURATION 15+'000 (AVG)
3 2017-08-12   19:01:04         26       0.0000          26        0.0000
4 2017-08-12   07:30:18     58,000       0.0000      57,000        0.0000
5 2017-08-12   04:29:38         27       0.0000          27        0.0000

从第 3 列开始,其余列被存储为字符向量。我正在尝试将字符转换为数字。以下是我使用的代码。

cols.num <- names(dat[,-c(1:2)])
dat[cols.num] <- sapply(dat[cols.num],as.numeric)

dat 是我的数据框。这会强制两个持续时间列中的 NA 值,其中字符值中有一个额外的逗号。

我试图删除它

df[,unique(grep("DUR", names(df), value=T))] <- gsub(",","",df[,unique(grep("DUR", names(df), value=T))])

但这会创建一个像这样的df

    Date Time (sec)           4+DURATION 4+'000 (AVG)          15+DURATION 15+'000 (AVG)
3 2017-08-12   19:01:04 c("26" "58000" "27")       0.0000 c("26" "57000" "27")        0.0000
4 2017-08-12   07:30:18 c("26" "57000" "27")       0.0000 c("26" "58000" "27")        0.0000
5 2017-08-12   04:29:38 c("26" "58000" "27")       0.0000 c("26" "57000" "27")        0.0000

但是想要的输出是:

   Date Time (sec) 4+DURATION 4+'000 (AVG) 15+DURATION 15+'000 (AVG)
3 2017-08-12   19:01:04         26       0.0000          26        0.0000
4 2017-08-12   07:30:18      58000       0.0000        57000        0.0000
5 2017-08-12   04:29:38         27       0.0000          27        0.0000

这个数据框的问题是,我不知道哪一列会有duration值,而duration值的列名一直在变化,从4+DURATION到45+DURATION等等。我想去掉逗号在将向量应用到数字之前,从名称中包含 DURATION 的所有向量中提取。

【问题讨论】:

你需要*apply它。 gsub 未矢量化。 df[,unique(grep("DUR", names(df), value=T))] &lt;- lapply(df[, unique(...))], function(i) gsub(...)) @Sotos 谢谢....明白了。我正在尝试申请……并陷入了永无止境的麻烦之中……可以接受这个作为答案。 【参考方案1】:

您需要将 *apply 它添加到感兴趣的列,因为 gsub(仅供参考,sub 在这里也可以使用)是矢量化的,即

df[,unique(grep("DUR", names(df), value=T))] <- 
                     lapply(df[,unique(grep("DUR", names(df), value=T))], function(i) 
                                                          as.numeric(sub(',', '', i)))

给出,

       Date Time (sec) 4+DURATION 4+'000 (AVG) 15+DURATION 15+'000 (AVG)
3 2017-08-12   19:01:04         26       0.0000          26        0.0000
4 2017-08-12   07:30:18      58000       0.0000       57000        0.0000
5 2017-08-12   04:29:38         27       0.0000          27        0.0000
#str(df)
#'data.frame':  3 obs. of  6 variables:
# $ Date         : chr  "2017-08-12" "2017-08-12" "2017-08-12"
# $ Time (sec)   : chr  "19:01:04" "07:30:18" "04:29:38"
# $ 4+DURATION   : num  26 58000 27
# $ 4+'000 (AVG) : chr  "0.0000" "0.0000" "0.0000"
# $ 15+DURATION  : num  26 57000 27
# $ 15+'000 (AVG): chr  "0.0000" "0.0000" "0.0000"

【讨论】:

【参考方案2】:

dplyr 解决方案:

d <- structure(list(Date = c("2017-08-12", "2017-08-12", "2017-08-12"
  ), `Time (sec)` = c("19:01:04", "07:30:18", "04:29:38"), `4+DURATION` = c("26", 
  "58,000", "27"), `4+'000 (AVG)` = c("0.0000", "0.0000", "0.0000"), 
  `15+DURATION` = c("26", "57,000", "27"), `15+'000 (AVG)` = c("0.0000", 
  "0.0000", "0.0000")), .Names = c("Date", "Time (sec)", "4+DURATION", 
   "4+'000 (AVG)", "15+DURATION", "15+'000 (AVG)"), row.names = 3:5, class = "data.frame")
d2 <- d %>% mutate_at(vars(contains('DURATION')), funs(as.numeric(gsub(',', '', .))))
str(d2)

【讨论】:

您也可以使用mutate_at(vars(contains('DURATION')), ~as.numeric(gsub(',', '', .))) 使用更多最近的dplyr pkg 版本 感谢您的建议!

以上是关于根据 R 中的特定列名从字符向量中删除逗号的主要内容,如果未能解决你的问题,请参考以下文章

从 R 中的字符向量中删除引号

从包含 R 中特定字符的字符串向量中删除条目 [重复]

R:从R中的大型数据集中根据列中的值删除行[重复]

如何根据包含的字符串的一部分选择列,然后在 R 中删除部分列名? (列位置可能不同)

将字符串中的逗号分隔数字转换为数字向量[重复]

删除R中数据框中所有列名的前两个字符