从字符串中提取数值并使用链接命令将其值相乘
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
包链接命令来代替循环函数:
- 提取值并根据其值进行乘法
到字符串中找到的相应字符(即,如果 M - 相乘
值乘以 10,如果 B - 值乘以 10)
- 保留其他所有内容(即,“-”保持原样,值前面的“-”表示负数)
仍然坚持下面的代码
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
也欢迎使用 apply
或 lappy
(如果有)的可能解决方案,因为我正在学习消除循环。
嗯,您不能将 "-"
本身作为与数值在同一列中的元素,那么 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))
下面显示了我的较大数据框的一小部分。
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
包链接命令来代替循环函数:
- 提取值并根据其值进行乘法 到字符串中找到的相应字符(即,如果 M - 相乘 值乘以 10,如果 B - 值乘以 10)
- 保留其他所有内容(即,“-”保持原样,值前面的“-”表示负数)
仍然坚持下面的代码
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
也欢迎使用 apply
或 lappy
(如果有)的可能解决方案,因为我正在学习消除循环。
嗯,您不能将 "-"
本身作为与数值在同一列中的元素,那么 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))