替换特定字符并除以余数

时间:2018-07-06 10:05:36

标签: r

我有以下示例数据框:

Date <- c("2013-01-01","2013-01-10","2013-01-16","2013-01-19")
concentration1 <- c("12","<10","<2","14")
concentration2 <- c("10","<10","<5","15")
y <- data.frame(Date, concentration1,concentration2)
y$Date <- as.Date(y$Date)

我需要在数据框中搜索“ <”符号,将其删除,然后将余数除以2。我试图使用以下代码获得结果:

y <- data.frame(lapply(y, function(x) {
  gsub("<", "", x)
 }))

但是,我无法将余数除以2。

更新:

这是我的原始代码,其中包含基于@RHertel回复的数据:

hw13<-read.csv("https://www.dropbox.com/s/dw6fket1b0bmoll/HW2013_%20Doemitz.csv?dl=1",sep=";",header=TRUE)

hw13$Datum<-as.Date(hw13$Datum, format="%d.%m.%Y")#convert to date
hw13[] <- lapply(hw13, as.character)     
hw13[sapply(hw13, startsWith, "<")] <- as.numeric(substring(hw13[sapply(hw13, startsWith, "<")],2)) / 2

4 个答案:

答案 0 :(得分:2)

y[2:3] <- lapply(y[2:3],function(x){
  x <- as.character(x) # if it's a factor
  flag    <- startsWith(x,"<")
  x       <- as.numeric(gsub("^<","",x))
  x[flag] <- x[flag] / 2
  x
})

#          Date concentration1 concentration2
# 1 2013-01-01             12           10.0
# 2 2013-01-10              5            5.0
# 3 2013-01-16              1            2.5
# 4 2013-01-19             14           15.0

答案 1 :(得分:2)

可以识别需要用sapply结合startsWith进行修改的条目,并执行所需的操作(删除<,转换为数字,除以2)这些元素。

y[] <- lapply(y, as.character)     
y[sapply(y, startsWith, "<")] <- as.numeric(substring(y[sapply(y, startsWith, "<")],2)) / 2

#> y
#        Date concentration1 concentration2
#1 2013-01-01             12             10
#2 2013-01-10              5              5
#3 2013-01-16              1            2.5
#4 2013-01-19             14             15

包含浓度的第2列和第3列可以转换为数字,如下所示:

y[2:3] <- sapply(y[2:3], as.numeric)

答案 2 :(得分:1)

正如斯蒂芬提到的,您需要转换为数字

data.frame(y[1], lapply(y[-1], function(x) as.numeric(gsub("<", "", x)) / 2))

#         Date concentration1 concentration2
# 1 2013-01-01              6            5.0
# 2 2013-01-10              5            5.0
# 3 2013-01-16              1            2.5
# 4 2013-01-19              7            7.5

回应评论。

首先确保在创建data.frame时将字符串作为字符读取。然后,通过转换为矩阵来避免循环(或* apply),并让R做它的向量化魔术。这不会覆盖原始的data.frame,而是创建一个新的data.frame。

y <- data.frame(Date, concentration1, concentration2, stringsAsFactors=FALSE)
y$Date <- as.Date(y$Date)

val <- as.matrix(y[,-1])
ind <- startsWith(val, "<")
val[ind] <- as.numeric(sub("<", "", val[ind])) / 2
data.frame(y[1], val)

#         Date concentration1 concentration2
# 1 2013-01-01             12             10
# 2 2013-01-10              5              5
# 3 2013-01-16              1            2.5
# 4 2013-01-19             14             15

答案 3 :(得分:1)

1)您需要记住带有'<'

的字段的索引

2)按照建议删除“ <”

3)除以2

4)再次将日期转换为日期格式

idx=lapply(y, function(x) grep("<",x) )
y=lapply(y, function(x) gsub("<", "", x)) 
y=data.frame(mapply(function(x,i){if(length(i)>0) x[i]=as.numeric(x[i])/2; x},y ,idx ))
y$Date <- as.Date(y$Date)

结果:

        Date concentration1 concentration2
1 2013-01-01             12             10
2 2013-01-10              5              5
3 2013-01-16              1            2.5
4 2013-01-19             14             15