R使用具有多个输入的plyr重值创建函数

时间:2021-08-01 19:14:00

标签: r function plyr

我是 R 的新手,刚刚学习绳索,所以提前感谢您提供的任何帮助。

我有一个数据集,作为课堂项目正在清理。

我有几组分类数据,我想将它们转换为特定的数值。

我正在为不同的列重复相同的代码格式,我认为这会成为一个很好的功能。

我想转这个:

# plyr using revalue
df$Area <- revalue(x = df$Area,
                   replace = c("rural" = 1,
                               "suburban" = 2,
                               "urban" = 3))

df$Area <- as.numeric(df$Area)

进入这个:

 reval_3 <- function(data, columnX,
                     value1, num_val1,
                     value2, num_val2,
                     value3, num_val3) {

  # plyr using revalue
  data$columnX <- revalue(x = data$columnX,
                        replace = c(value1 = num_val1,
                                    value2 = num_val2,
                                    value3 = num_val3))

  # set as numeric
  data$columnX <- as.numeric(data$columnX)

  # return dataset
  return(data)

}

我收到以下错误:

The following `from` values were not present in `x`: value1, value2, value3
Error: Assigned data `as.numeric(data$columnX)` must be compatible with existing data.
x Existing data has 10000 rows.
x Assigned data has 0 rows.
ℹ Only vectors of size 1 are recycled.
Run `rlang::last_error()` to see where the error occurred.
In addition: Warning messages:
1: Unknown or uninitialised column: `columnX`. 

我用单个 value1 尝试过,其中 value1 <- c("rural" = 1, "suburban" = 2, "urban" = 3)

我知道我可以:

df$Area <- as.numeric(as.factor(df$Area))

数据,但我想要每个选择的特定值,而不是 R 选择。

感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

正如@MartinGal 在他的评论中已经提到的,plyr 已停用,软件包作者自己建议改用 dplyr。见https://github.com/hadley/plyr

因此,实现您想要的结果的一种选择是使用 dplyr::recode。此外,如果您想编写函数,我建议将要重新编码的值和替换作为向量传递,而不是将每个值和替换作为单独的参数传递:

library(dplyr)

set.seed(42)

df <- data.frame(
  Area = sample(c("rural", "suburban", "urban"), 10, replace = TRUE)
)

recode_table <- c("rural" = 1, "suburban" = 2, "urban" = 3)

recode(df$Area, !!!recode_table)
#>  [1] 1 1 1 1 2 2 2 1 3 3

reval_3 <- function(data, x, values, replacements) {
  recode_table <- setNames(replacements, values)  
  data[[x]] <- recode(data[[x]], !!!recode_table)
  data
}

df <- reval_3(df, "Area", c("rural", "suburban", "urban"), 1:3)
df
#>    Area
#> 1     1
#> 2     1
#> 3     1
#> 4     1
#> 5     2
#> 6     2
#> 7     2
#> 8     1
#> 9     3
#> 10    3

答案 1 :(得分:0)

您可以将 case_whenacross 一起使用。

如果您要更改的列名为 col1, col2 您可以这样做 -

library(dplyr)

df <- df %>%
  mutate(across(c(col1, col2), ~case_when(. == 'rural' ~ 1, 
                          . == 'suburban' ~ 2, 
                          . == 'urban' ~ 3)))

根据您的实际列名,您还可以在 starts_with 中传递 ends_withA:Z、列范围 across