微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将自定义函数应用于现有列以在 R 中的数据框中创建新列的最佳方法

如何解决将自定义函数应用于现有列以在 R 中的数据框中创建新列的最佳方法

我有一个数据框,其中包含一个字符类型的列,其中包含以逗号分隔的数字字符串,即 1,2,3,4 我有一个自定义函数,我想将它逐行应用于列中的每个值,以便获得一个新值,该值可以存储到数据框 df 的新列中。

初始数据框

A B str
1 1 1,5
1 2 NA
2 1 NA
2 2 1,3

最终数据框

A B str      res
1 1 1,5  2
1 2 NA       0
2 1 NA       0
2 2 1,3     1

这是我的自定义函数 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))
}


我最初尝试使用 lapply,因为根据其他帖子,它似乎最适合,但一直收到错误,例如:

df <- df %>% mutate(res = lapply(df$str,getCounts(df$str,2)))
Error: Problem with `mutate()` input `res`. x missing value where TRUE/FALSE needed i Input `res` is `lapply(df$str,2))`

似乎唯一有效的是当我使用 mapply 时,但我真的不明白为什么以及是否有更好的方法来做到这一点。

df <- df %>%mutate(res = mapply(getCounts,df$str,2))

解决方法

如果我没看错的话,你应该可以使用 rowwise():

df %>%
  rowwise() %>%
  mutate(res = getCounts(str,2)) %>%
  ungroup()

使用您的数据:

data.frame(
    A = c(1,1,2,2),B = c(1,str = c('1,5',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,2)) %>%
    ungroup()
#> # A tibble: 4 x 4
#>       A     B str       res
#>   <dbl> <dbl> <chr>   <int>
#> 1     1     1 1,5     2
#> 2     1     2 <NA>        0
#> 3     2     1 <NA>        0
#> 4     2     2 1,3        1

reprex package (v1.0.0) 于 2021 年 3 月 17 日创建

,

你可以试试Vectorize

df %>%
  mutate(res = Vectorize(getCounts)(str,2))

sapply

df %>%
  mutate(res = sapply(str,getCounts,x = 0,y = 2))

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。