繁体   English   中英

R:For循环在列表中起作用,而不是单个元素

[英]R: For loop works on list, not individual element

我正在尝试通过编写函数来学习。 它将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)

列表的索引可能有问题。 您是否曾尝试在strsplit函数之后使用[[1]]

例:

string <- "Hello/world"
mylist <- strsplit(string, "/")
## [[1]]
## [1] "Hello" "World"

但是,如果我们明确地说要使用[[1]]作为列表的第一个“元素”,我们将拥有字符串的整个数组。

例:

string <- "Hello/World"
mylist <- strsplit(string, "/")[[1]]
## [1] "Hello" "World"

希望这可以帮助您解决问题。

这里有一些问题。 您遇到的主要问题是s是一个长度为1的列表。在该列表中,第一个(唯一的)元素是长度为2的向量。因此,您需要i in s[[1]]设置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)

我不知道这是否是您要尝试的方法,但是在从“ 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM