R:将百分比数据框从因子转换为数字

时间:2015-03-11 02:52:25

标签: r

遇到将数据框转换为R的问题。

我有一堆列被视为factors,并带有%个符号。

我知道我可以做一个专栏:

df[,3] <- as.numeric(sub("%","",df[,3]))

但是尝试将其应用于整个数据集似乎不起作用并将所有值更改为NA。我究竟做错了什么?这是我尝试使用的代码:

df[,-1] <- as.numeric(sub("%","",df[,-1]))

编辑:我知道我可以用以下方法解决这个问题:

for (i in 2:66) {
df[,i] <- as.numeric(sub("%","",df[,i]))
print(class(df[,i]))
}

但必须有更优雅(并且希望是单行)的方式来做到这一点。

编辑2:以下是一些数据:

    Year        v1      v2       v3       v4
1 12-Oct        0%      0%      39%      14%
2 12-Nov        0%      6%      59%       4%
3 12-Dec       22%      0%      37%      26%
4 13-Jan       45%      0%      66%      19%
5 13-Feb       28%     39%      74%      13%

答案:以下是我们帮助了我之后在一个命令中执行此操作的方法!我在指定功能部分时遇到了问题。

df=read.csv("all response rates.csv")
df[-1]<-data.frame(apply(df[-1], 2, function(x) 
    as.numeric(sub("%","",as.character(x)))))

4 个答案:

答案 0 :(得分:6)

来自parse_number包的

readr将删除%符号。对于您的给定数据集,请尝试:

library(dplyr)
library(readr)

res <- cbind(df %>% select(Year), # preserve the year column as-is
             df %>% select(-Year) %>% mutate_all(funs(parse_number))
             )

> res
    Year v1 v2 v3 v4
1 12-Oct  0  0 39 14
2 12-Nov  0  6 59  4
3 12-Dec 22  0 37 26
4 13-Jan 45  0 66 19
5 13-Feb 28 39 74 13

如果您不需要保留第一列,则只需要摘录:

df %>% select(-Year) %>% mutate_all(funs(parse_number))

答案 1 :(得分:3)

以下是使用set data.table的选项,对于大数据集来说会更快,因为可以避免[.data.table的开销

library(stringi)
library(data.table)

setDT(df)
for(j in 2:ncol(df)){
     set(df, i=NULL, j=j, value= as.numeric(stri_extract(df[[j]], regex='\\d+')))
}

df
#     Year v1 v2 v3 v4
#1: 12-Oct  0  0 39 14
#2: 12-Nov  0  6 59  4
#3: 12-Dec 22  0 37 26
#4: 13-Jan 45  0 66 19
#5: 13-Feb 28 39 74 13

答案 2 :(得分:1)

使用base

中的函数尝试此方法
# dummy data:
df<-data.frame(v1=c("78%", "65%", "32%"), v2=c("43%", "56%", "23%"))

# function
df2<-data.frame(lapply(df, function(x) as.numeric(sub("%", "", x))) )

根据提供的评论,首先删除百分号,然后将列从因子转换为数字。我已根据@ thelatemail的建议将原始回答从apply更改为lapply

答案 3 :(得分:0)

这是一行解决方案,假设数据位于固定宽度列中。我需要删除第一行名称,因为所有列都没有名称。列的宽度指定为整数(含义为跳过那么多字符。)它还会在读取期间将列类更改为数字。

your data

1 12-Oct        0%      0%      39%      14%
2 12-Nov        0%      6%      59%       4%
3 12-Dec       22%      0%      37%      26%
4 13-Jan       45%      0%      66%      19%
5 13-Feb       28%     39%      74%      13%

the R one-line script

adf <- read.fwf(file="a.dat",widths=c(-8,9,-1,7,-1,8,-1,8),colClasses=rep("numeric",4))

output result (first col provided by R to count the rows)

  V1 V2 V3 V4
1  0  0 39 14
2  0  6 59  4
3 22  0 37 26
4 45  0 66 19
5 28 39 74 13