将因子转换成比例值

时间:2019-06-18 04:40:39

标签: r

我有团队排名数据,其中一列具有“ Xth of Y”形式的条目。我需要将它们转换为0到1比例的数值,其中1st是1,last是0,其余部分以线性比例出现。我已经考虑过strsplit(),但是不知道该如何处理某些“第一”,某些“第二”等。举个例子,我的数据看起来像

x = as.factor(c('2nd of 6', '5th of 5', '4th of 5', '3rd of 5', '5th of 5', '4th of 7'))

注意:“ 6之2”应转换为0.8,而不是0.6666667

2 个答案:

答案 0 :(得分:2)

我们可以从字符串中提取数字,将其分割,然后创建一个介于0和1之间的序列,其长度由第二个数字决定,并从该序列中将第一个数字作为子集。

sapply(strsplit(sub("^(\\d+)(?:st|nd|rd|th) of (\\d+).*", "\\1-\\2", x), "-"), 
   function(x)  1 - seq(0, 1, length.out = as.integer(x[2]))[as.integer(x[1])])

#[1] 0.80 0.00 0.25 0.50 0.00 0.50

答案 1 :(得分:1)

更新

OP之前没有提到预期的输出。因此,我们将根据另一篇文章的评论更改输出。

df1 <- read.csv(text= gsub("\\D+", ",", x), header = FALSE)
1 - unlist(Map(function(x, y) seq(0, 1, length.out = y)[x], df1$V1, df1$V2))
#[1] 0.80 0.00 0.25 0.50 0.00 0.50

我们可以使用base R单行执行

1- Reduce(`/`, read.csv(text= gsub("\\D+", ",", x), header = FALSE))
#[1] 0.6666667 0.0000000 0.2000000 0.4000000 0.0000000 0.4285714

或与strsplit

m1 <- sapply(strsplit(as.character(x), "\\D+"), as.numeric)
1 - m1[1,]/m1[2,]

或与fread

library(data.table)
fread(text=gsub("\\D+", ",", x))[, 1- Reduce(`/`, .SD)]
#[1] 0.6666667 0.0000000 0.2000000 0.4000000 0.0000000 0.4285714

或使用tidyverse

library(tidyverse)
x %>%
   str_replace("\\D+", ",") %>% 
   tibble(col1 = .) %>% 
   separate(col1, into = c('col1', 'col2'), convert = TRUE) %>% 
   reduce(`/`) %>%
    -1 *-1
#[1] 0.6666667 0.0000000 0.2000000 0.4000000 0.0000000 0.4285714
相关问题