[英]Best way to apply a custom function to existing column to create a new column in data frame in R
I have a data frame with a character-type column containing strings of numbers in a comma-delimited manner ie 1, 2, 3, 4
.我有一个数据框,其字符类型列包含以逗号分隔的数字字符串,即
1, 2, 3, 4
。 I have a custom function that I would like to apply to each value row-wise in the column in order to get a new value that I can store into a new column to the data frame df
.我有一个自定义 function ,我想将其应用于列中的每个值,以便获得一个可以存储到数据框
df
的新列中的新值。
Initial data frame初始数据框
A B str
1 1 1, 2, 5
1 2 NA
2 1 NA
2 2 1, 3
Final data frame最终数据框
A B str res
1 1 1, 2, 5 2
1 2 NA 0
2 1 NA 0
2 2 1, 3 1
This is my custom function getCounts这是我的自定义 function getCounts
getCounts <- function(str, x, y){
if (is.na(str)){
return(as.integer(0))
}
vec <- as.integer(unlist(strsplit(str, ',')))
count <- 0
for (i in vec) {
if (i >= x & i <= y){
count <- count + 1
}
}
return(as.integer(count))
}
I originally tried using lapply
as it seemed like it was best suited based on other posts but kept getting an error such as:我最初尝试使用
lapply
,因为它似乎最适合基于其他帖子,但不断收到错误,例如:
df <- df %>% mutate(res = lapply(df$str, getCounts(df$str, 0, 2)))
Error: Problem with `mutate()` input `res`. x missing value where TRUE/FALSE needed i Input `res` is `lapply(df$str, getCounts(df$str, 0, 2))`
The only thing that seems to be working is when I use mapply
, but I don't really understand why and if there is a better way to do this.唯一似乎有效的是当我使用时
mapply
,但我真的不明白为什么以及是否有更好的方法来做到这一点。
df <- df %>%mutate(res = mapply(getCounts, df$str, 0, 2))
If I'm reading this right, you should be able to just use rowwise()
:如果我没看错,您应该可以使用
rowwise()
:
df %>%
rowwise() %>%
mutate(res = getCounts(str, 0, 2)) %>%
ungroup()
with your data:使用您的数据:
data.frame(
A = c(1,1,2,2),
B = c(1,2,1,2),
str = c('1, 2, 5', NA, NA, '1, 3')
) -> df
getCounts <- function(str, x, y){
if (is.na(str)){
return(as.integer(0))
}
vec <- as.integer(unlist(strsplit(str, ',')))
count <- 0
for (i in vec) {
if (i >= x & i <= y){
count <- count + 1
}
}
return(as.integer(count))
}
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
df %>%
rowwise() %>%
mutate(res = getCounts(str, 0, 2)) %>%
ungroup()
#> # A tibble: 4 x 4
#> A B str res
#> <dbl> <dbl> <chr> <int>
#> 1 1 1 1, 2, 5 2
#> 2 1 2 <NA> 0
#> 3 2 1 <NA> 0
#> 4 2 2 1, 3 1
Created on 2021-03-17 by the reprex package (v1.0.0)由代表 package (v1.0.0) 于 2021 年 3 月 17 日创建
You can try Vectorize
你可以试试
Vectorize
df %>%
mutate(res = Vectorize(getCounts)(str, 0, 2))
or sapply
或
sapply
df %>%
mutate(res = sapply(str, getCounts, x = 0, y = 2))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.