R-操作数据帧中的列,通过将字符转换为数字来消除审查值



以下是我正在使用的数据的迷你版本:

columnNum <- c("G1", "G2", "G3")
Al <- c("<5", 6, 7, "<4", 5, 6)
Ca <- c(9, 10, 11,10, 11, 12)
df <- data.frame(columnNum, Al, Ca, stringsAsFactors = FALSE)

目前,由于某些值被审查(包含"<"),每列的类都是字符、字符、数字(按从左到右的顺序)

我想做的是将"Al"列中的值替换为实际的数值,而不是字符串。我确信我可以找到一种方法,只为一个专栏做这件事,但我的问题是,实际上,我有20个不同的专栏,而不是2个。我需要浏览每一列(从"Al"列到"Zn"列),检查值是否经过审查,如果是,去掉"<"并将其转换为数字。

我还是个新手,所以这就是我试图做的(在我的大数据上,而不是这个小数据上):

for(i in df$Al:df$Zn)
{
   if (class(df[[i]]) != numeric)
   {
      df[[i]] <-  as.numeric(gsub(pattern = "<", replacement =    
      "", df[[i]])) 
   }
}

循环永远不会结束。

我们应该首先找到要调整的列。我们根据您对从AlZn的列的描述来执行此操作。接下来,我们sub不必要的字符,并使用numerize函数转换为numeric。我添加了更多的列来显示复杂性:

cols <- match("Al", names(df)):match("Zn", names(df))
numerize <- function(x) as.numeric(sub(".*?([0-9.-]+).*", "\1", x))
#base R
df[cols] <- lapply(df[cols], numerize)
#dplyr
df %>% mutate_at(vars(Al:Zn), numerize)
#data.table
setDT(df)[, (names(df)[cols]) := lapply(.SD, numerize), .SDcols=cols][]
#   columnNum Al Yw Zn Ca
# 1        G1  5  8  1  9
# 2        G2  6  6  6 10
# 3        G3  7  7  7 11
# 4        G1  4  4  4 10
# 5        G2  5  5  5 11
# 6        G3  6  6  6 12

数据

columnNum <- c("G1", "G2", "G3")
Al <- c("<5", 6, 7, "<4", 5, 6)
Yw <- c("<8", 6, 7, "<4", 5, 6)
Zn <- c("<1", 6, 7, "<4", 5, 6)
Ca <- c(9, 10, 11,10, 11, 12)
df <- data.frame(columnNum, Al, Yw, Zn, Ca, stringsAsFactors = FALSE)

tidyr::extract_numeric很方便,无论是否在dplyr中:

df$Al <- tidyr::extract_numeric(Al)    # or df %>% mutate(Al = extract_numeric(Al))

大致相当于

df$Al <- as.numeric(sub('.*(-?[0-9]+.?[0-9]*).*', '\1', df$Al))

对于这种特殊情况,可以简化为:

df$Al <- as.integer(sub('<', '', df$Al))

无论您使用哪种数据,您都可以获得以下数据:

##   columnNum Al Ca
## 1        G1  5  9
## 2        G2  6 10
## 3        G3  7 11
## 4        G1  4 10
## 5        G2  5 11
## 6        G3  6 12

最新更新