我正在尝试通过编写函数来学习。它将UOM(度量单位)转换为标准UOM的一部分。在这种情况下,为1/10或0.1
我试图遍历从strsplit生成的列表,但是我只得到整个列表,而不是列表中的每个元素。我不知道我在做什么错。是strsplit错误的功能吗?我不认为问题出在strsplit上,但我无法弄清楚我在For循环中做错了什么:
qty<-0
convf<-0
uom <- "EA"
std <- "CA"
pack <-"1EA/10CA"
if(uom!=std){
s<-strsplit(pack,split = '/')
for (i in s){
print(i)
if(grep(uom,i)){
qty<- regmatches(i,regexpr('[0-9]+',i))
}
if(grep(std,i)){
convf<-regmatches(i, regexpr('[0-9]+',i))
}
} #end for
qty<-as.numeric(qty)
convf<-as.numeric(convf)
}
return(qty/convf)
答案 0 :(得分:0)
列表的索引可能有问题。在[[1]]
函数之后,您是否尝试过使用strsplit
?
示例:
string <- "Hello/world"
mylist <- strsplit(string, "/")
## [[1]]
## [1] "Hello" "World"
但是,如果我们明确地说希望使用[[1]]
列表的第一个“元素”,则将具有字符串的整个数组。
示例:
string <- "Hello/World"
mylist <- strsplit(string, "/")[[1]]
## [1] "Hello" "World"
希望这可以帮助您解决问题。
答案 1 :(得分:0)
这里有一些问题。您遇到的主要问题是s
是一个长度为1的列表。在该列表中,第一个(唯一的)元素是一个长度为2的向量。因此,您需要设置i in s[[1]]
。
但是,我们可以更进一步。尝试以下代码:
library(stringr)
lapply(strsplit(pack,split = '/'), # works within the list, can handle larger vectors for `pack`
function(x, uom, std) {
reg_expr <- paste(uom,std, sep = "|") # call this on its own, it's just searching for the text saved in uom or std
qty <- as.numeric(str_remove(x, reg_expr)) # removes that text and converts the string to a number
names(qty) <- str_extract(x, reg_expr) # extracts the text and uses it to name elements in qty
qty[uom] / qty[std] # your desired result.
},
uom = uom, # since these are part of the function call, we need to specify what they are. This is where you should change them.
std = std)
答案 2 :(得分:0)
我不知道这是否是您要尝试的方法,但是在从类似“ 1EA / 10CA”的字符串中提取数字时,我会避免循环。如果有帮助,列lst
实际上是数据集中的一个列表。
library(magrittr)
ds <- data.frame(pack = c("1EA/10CA", "1EA/4CA", "2EA/2CA"))
pattern <- "^(\\d+)EA/(\\d+)CA$"
ds %>%
dplyr::mutate(
qty = as.numeric(sub(pattern, "\\1", pack)),
convf = as.numeric(sub(pattern, "\\2", pack)),
ratio = qty / convf,
lst = purrr::map2(qty, convf, ~list(qty=.x[[1]], convf=.y[[1]]))
)
结果:
pack qty convf ratio lst
1 1EA/10CA 1 10 0.10 1, 10
2 1EA/4CA 1 4 0.25 1, 4
3 2EA/2CA 2 2 1.00 2, 2