R函数未分配值

时间:2019-04-05 15:57:28

标签: r tidyverse

使用来自Kaggle here的波士顿住房数据train.csv。我试图编写一个函数来将GarageYrBlt列的值更改为0(如果该行包含NA值或已经为0,否则为1)。

此列包含建造车库的年份,但缺少值和零。

我对R比较陌生,将下面的函数拼凑在一起以尝试替换此列中的值。

library(tidyverse)
housing_prices <- read_csv('../input/train.csv')


garage <- function(x) {
    for (i in 1:length(x)){
    if (is.na(x[i])) {
       x[i] = 0}
    else if (x[i] > 0) { 
        x[i] = 1} 
    else x[i]=0}
}

garage(housing_prices$GarageYrBlt)

如果我在函数的最后一个花括号前放置一个print(x)语句,我可以看到逻辑工作正常。但是,它不会将值分配回GarageYrBlt列。我知道我在这里缺少一些简单的东西。

此外,如果任何人都知道实现此目标的矢量化方法或总体上具有其他任何技巧,则总是会非常感谢他们。

2 个答案:

答案 0 :(得分:2)

函数返回最后一个值。将xreturn(x)放在函数的末尾,以便将修改后的x从函数中退回。

garage <- function(x) {
    for (i in 1:length(x)) {
        if (is.na(x[i])) {
            x[i] = 0}
        else if (x[i] > 0) { 
            x[i] = 1
        } 
        else x[i] = 0
    }
    x
}

然后,如果要分配结果,则需要用=<-分配它

housing_prices$GarageYrBlt = garage(housing_prices$GarageYrBlt)

当然,我们可以在for循环中使用向量化ifelse代替if

housing_prices$GarageYrBlt = ifelse(is.na(housing_prices$GarageYrBlt), 0,
     ifelse(housing_prices$GarageYrBlt > 0, 1, 0)) 

由于您放置了tidyverse标记,因此在dplyr中进行标记的一种更好的方法是使用case_when

housing_prices %>% 
  mutate(GarageYrBlt = case_when(
    is.na(GarageYrBlt) ~ 0,
    GarageYrBlt > 0 ~ 1,
    TRUE ~ 0
))

或者,coalesce()是一个不错的dplyr实用程序,用于填充NA的值,所以我们可以这样做

housing_prices %>% 
  mutate(GarageYrBlt = ifelse(coalesce(GarageYrBlt, 0) > 0, 1, 0))

或者,甚至更有趣的是,我们可以使用TRUE到1以及FALSE到0的默认转换:

housing_prices %>% 
  mutate(GarageYrBlt = as.integer(coalesce(GarageYrBlt, 0) > 0))

答案 1 :(得分:0)

您应该可以使用dplyr。

library(dplyr)
housing_prices <- housing_prices %>%
    mutate(GarageYrBlt = if_else(is.na(GarageYrBlt),0,GarageYrBlt)