从字符串中提取数值并使用链接命令将其值相乘

Extract numeric value out of string and multiply its value using chaining command

下面显示了我的较大数据框的一小部分。

  V0      V1          V2          V3          V4           V5
3301    2012    404.46 M    -            14.34 M     215.61 M
3336    2011    3.9677 B    685.69 M     76.69 M     -0.699 B
3379    2010    61.154 M    -            26.05 M    334.199 M
3395    2013    2.8834 B    18.531 M      6.02 B      1.939 B
3417    2013    296.64 M    -           -3.231 M    268.535 M

("datss"数据包含六列混合字符,感兴趣的数值仅在V2至V5列)

我正在尝试使用 R dplyr 包链接命令来代替循环函数:

  1. 提取值并根据其值进行乘法 到字符串中找到的相应字符(即,如果 M - 相乘 值乘以 10,如果 B - 值乘以 10)
  2. 保留其他所有内容(即,“-”保持原样,值前面的“-”表示负数)

仍然坚持下面的代码

library(dplyr)
tesdt <- tbl_df(datss)
tesdt %>% 
    as.numeric(sub(" M", "", tesdt)) %>%    #this one works
    mutate(tesdt, tesdt[,2:6]*10)           #how to do on multiple col

也欢迎使用 applylappy(如果有)的可能解决方案,因为我正在学习消除循环。

嗯,您不能将 "-" 本身作为与数值在同一列中的元素,那么 NA 怎么样?这是一个 lapply() 方法

df[-(1:2)] <- lapply(df[-(1:2)], function(x) {
    suppressWarnings(as.numeric(gsub(" (M|B)", "", x)) * 10)
})

dplyr,

library(dplyr)
mutate_each(df, funs(suppressWarnings(as.numeric(gsub(" (M|B)", "", .))) * 10), -c(V0, V1))

任一个给

    V0   V1       V2      V3     V4      V5
1 3301 2012 4044.600      NA 143.40 2156.10
2 3336 2011   39.677 6856.90 766.90   -6.99
3 3379 2010  611.540      NA 260.50 3341.99
4 3395 2013   28.834  185.31  60.20   19.39
5 3417 2013 2966.400      NA -32.31 2685.35

根据您的评论,您可以编写一个小函数,以便您可以查找任一字母,然后一次性乘以其对应的值。

f <- function(x, regex, mult) {
    suppressWarnings(as.numeric(sub(regex, "", x)) * mult)
} 

df[-(1:2)] <- lapply(df[-(1:2)], function(x) {
    ifelse(sub(".* ", "", x) == "M", f(x, " M", 10), f(x, " B", 100))
})

df
#     V0   V1      V2      V3     V4      V5
# 1 3301 2012 4044.60      NA 143.40 2156.10
# 2 3336 2011  396.77 6856.90 766.90  -69.90
# 3 3379 2010  611.54      NA 260.50 3341.99
# 4 3395 2013  288.34  185.31 602.00  193.90
# 5 3417 2013 2966.40      NA -32.31 2685.35

数据:

df <- structure(list(V0 = c(3301L, 3336L, 3379L, 3395L, 3417L), V1 = c(2012L, 
2011L, 2010L, 2013L, 2013L), V2 = structure(c(4L, 3L, 5L, 1L, 
2L), .Label = c("2.8834 B", "296.64 M", "3.9677 B", "404.46 M", 
"61.154 M"), class = "factor"), V3 = structure(c(1L, 3L, 1L, 
2L, 1L), .Label = c("-", "18.531 M", "685.69 M"), class = "factor"), 
    V4 = structure(c(2L, 5L, 3L, 4L, 1L), .Label = c("-3.231 M", 
    "14.34 M", "26.05 M", "6.02 B", "76.69 M"), class = "factor"), 
    V5 = structure(c(3L, 1L, 5L, 2L, 4L), .Label = c("-0.699 B", 
    "1.939 B", "215.61 M", "268.535 M", "334.199 M"), class = "factor")), .Names = c("V0", 
"V1", "V2", "V3", "V4", "V5"), class = "data.frame", row.names = c(NA, 
-5L))