我有一个导入R的数据框,有大约180列和1000个带字符串值的记录。这些字符串可以是单个单词或单词组合,例如(“好”,“非常好”)。他们有像撇号这样的特殊字符(“不知道”)。
我正在尝试使用数字查找并替换多列中的特定字符串值,以便我可以处理它们。
我已将感兴趣的列存储到变量中,因此我不必一次又一次地提及这些名称。数据集中的名称太长,并且有很多“。”在他们中。
提供可重现的代码作为样本。
set.seed(12)
datwe <- data.frame(replicate(37,sample(c("ABC’o /BBB","XYZ","FoO","ABC'o /BBB",NA),10,rep=TRUE)))
> str(datwe)
'data.frame': 10 obs. of 37 variables:
$ X1 : Factor w/ 3 levels "ABC'o /BBB","ABC’o /BBB",..: 2 NA NA 3 2 2 2 1 2 2
$ X2 : Factor w/ 4 levels "ABC'o /BBB","ABC’o /BBB",..: 4 NA 4 4 4 3 3 3 1 2
$ X3 : Factor w/ 4 levels "ABC'o /BBB","ABC’o /BBB",..: 4 1 2 1 4 4 3 2 3 1
$ X4 : Factor w/ 2 levels "ABC'o /BBB","XYZ": 2 NA NA NA 1 NA 1 NA 2 2
请注意,“ABC'o / BBB”,“ABC'o / BBB”并不相同,即使它们可以被阅读。
感兴趣的列在v
中v=c(names(datwe[3:6]),names(datwe[9]),names(datwe[12]))
我想用-100替换“ABC'o / BBB”,用4替换“FoO”,用5替换“XYZ”。 v和其他列中的这些列在实际数据中也具有NA,其必须保持为NA。我的最终目标是对这些专栏做一些总结,找出总和,意思等等。哪些列比另一列更好。
我已经尝试了以下代码,它已经部分工作了。我已经能够将F0O替换为4,但不能将“ABC'o / BBB”替换为数据中的(')并且R不匹配,并且它不会选择相关数据。
datwe[v]<- replace(datwe[v],datwe[v]=="FoO","4")
datwe[v]<- replace(datwe[v],datwe[v]=="ABC'o /BBB","-100")
这已失败
datwe[grepl("^ABC",datwe[,v],perl=TRUE),datwe[,v]]<-"-100"
我尝试使用sqldf来执行更新stmt,这也失败了。
for(mycols in v)
sqldf("update datwe set $mycols='-100' where $mycols like 'AB%'")
请帮忙!
感谢@amrrs和@Hugh提供解决方案。我编辑了样本数据,以反映更接近实际数据的数据。
我按照@amrrs
的建议尝试了以下代码datwe[v] <- lapply(datwe[v],
function(x){ifelse(x=="FoO","4",
ifelse(x=="XYZ","5",
ifelse(x=="ABC'o /BBB","-100",x)))})
但“ABC'o / BBB”转换为2而不是-100,无法找到完全匹配。
我认为问题是由于R和源数据的引用(')不同。
实际数据有不同形式的单引号(不要,不要)。
我尝试了@Hugh提供的实际数据解决方案
datwe_melt <-
datwe[, id := .I] %>%
melt.data.table(id.vars = "id")
这很好用,并将列创建为变量和正确的值。
datwe_melt_modified<-datwe_melt[decoder, on = "value==old"] %>%
dcast.data.table(id ~ variable, value.var = "new")
dcast代码给出了以下警告。
Aggregate function missing, defaulting to 'length'
和0代替NA,1代替非NA;并包含一个名为NA的新列。解码器来自Excel文件。 样本数据中的NA被正确处理,而在实际数据中,它给出了新列和新行。我知道我还没有理解dcast要对其进行故障排除。 检查了 here 和here 给出的解决方案,但我无法解决我的问题。
我希望有一个有效的解决方案,而不是特别提到所有形式的报价。
是否有办法在SQL中提供类似'AB%'的类似内容,它应该替换所有以“AB”开头的内容
答案 0 :(得分:1)
乌拉!我能够在SQL中忽略引号问题(例如&#34; ABC%&#34;)
// Add or remove paths from the annotation.
// Path points are specified in annotation space.
// Used by annotations type(s): /Ink.
open func add(_ path: UIBezierPath)
感谢@amrrs带我走向正确的方向!
希望这有助于其他希望解决类似问题的人。我相信可以有更好的方法。愿意接受建议!!
答案 1 :(得分:0)
由于引号,您的grepl
可能无效。所以ifelse
应该!
set.seed(12)
datwe <- data.frame(replicate(37,sample(c("ABC'o /BBB","XYZ","FoO"),10,rep=TRUE)))
v=c(names(datwe[3:6]),names(datwe[9]),names(datwe[12]))
datwe[v] <- lapply(datwe[v],function(x){ifelse(x=="ABC'o /BBB",-100,ifelse(x=="FoO",1,ifelse(x=='XYZ',2,x)))})
datwe
答案 2 :(得分:0)
每当你想要“解码”表中的值时,你应该想“如何在这里使用连接”?
这是一个data.table
解决方案。 magrittr
仅适用于%>%
。我们首先melt
表格,以便所有值都在一列中。然后我们使用查找表(decoder
)解码该表。 dcast.data.table
与melt.data.table
相反 - 函数将熔化的data.table
恢复为原始形式
set.seed(12)
datwe <- data.frame(replicate(37,sample(c("ABC'o /BBB","XYZ","FoO"),10,rep=TRUE)))
library(data.table)
library(magrittr)
setDT(datwe)
datwe_melt <-
datwe[, id := .I] %>%
melt.data.table(id.vars = "id")
decoder <-
data.table(old = c("ABC'o /BBB","XYZ","FoO"),
new = c(-100, 2, 1))
datwe_melt[decoder, on = "value==old"] %>%
dcast.data.table(id ~ variable, value.var = "new")
请注意,在data.table
之后使用datwe_melt[decoder, on = "value==old"]
可能会更好,因为在具有此结构的表上运行查询通常更容易。