在R

时间:2017-09-22 05:42:03

标签: r

我有一个导入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”开头的内容

3 个答案:

答案 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.tablemelt.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"]可能会更好,因为在具有此结构的表上运行查询通常更容易。