我有一个包含字符串的向量,每个字符串包含一个字母数字代码,其中整数的值为 1-3(例如“1RV2GA”)。我想提取数字并得到它们的总和。因此对于“1RV2GA”,它应该提取 1 和 2 并将它们相加得到 3。
我已经弄清楚如何在单个字符串上执行此操作:
str_extract_all(
"1RV2GA", "\\(?[0-3,.]+\\)?", simplify = T) %>%
as.numeric() %>% sum()
[1] 3
我的问题是,我不知道如何让它在整个向量上工作。
str_extract_all()
返回一个列表,因此这显然会导致 mutate 中出现问题,但我只需要每行的总和。
要制作一些示例数据,请在此处:
test<-data.frame(ID=c("2VG1AR", "1OR2AG", "1GV1OA"),
value = c(4,8,2))
> test
ID value
1 2VG1AR 4
2 1OR2AG 8
3 1GV1OA 2
通常
str_extract_all()
会处理这样的向量,返回字符向量列表:
> str_extract_all(test$ID, "\\(?[0-3,.]+\\)?")
[[1]]
[1] "2" "1"
[[2]]
[1] "1" "2"
[[3]]
[1] "1" "1"
但显然,为了获得每个输入值的输出向量的总和,我需要它们是数字,或者我需要一个为原子向量输入设计的函数。如果我尝试使用
simplify=T
执行 mutate 命令,则会返回 ID 向量中所有值的总和:
test %>% mutate(ID.numsum =
str_extract_all(ID, "\\(?[0-3,.]+\\)?", simplify = T) %>%
as.numeric() %>% sum())
ID value ID.numsum
1 2VG1AR 4 8
2 1OR2AG 8 8
3 1GV1OA 2 8
如果我只是尝试获取
str_extract_all()
列表输出的第一个元素,它只会返回整个新向量中“2VG1AR”的正确值。:
test%>%mutate(ID.numsum = str_extract_all(ID, "\\(?[0-3,.]+\\)?")[[1]] %>%
as.numeric() %>% sum())
# A tibble: 3 × 3
ID value ID.numsum
<chr> <dbl> <dbl>
1 2VG1AR 4 3
2 1OR2AG 8 3
3 1GV1OA 2 3
str_extract()
也不起作用,因为它只提取每个字符串中的第一个数字,所以如果我在“2VG1AR”上尝试它,它会返回 2,其中我需要一个包含 2 和 1 的向量,以便我可以将它们加起来为 3。
这里有人有解决办法吗?
sum()
是一个折叠函数。以行方式使用这些函数时必须小心。您可以在列表上显式 map()
。例如
test %>% mutate(ID.numsum =
purrr::map_int(stringr::str_extract_all(ID, "\\(?[0-3,.]+\\)?"),
~sum(as.numeric(.))))
或者你可以使用
rowwise()
test %>%
rowwise() %>%
mutate(ID.numsum =
stringr::str_extract_all(ID, "\\(?[0-3,.]+\\)?") |> unlist() |> as.numeric() |> sum())