为重复性任务创建函数或For循环

k4ymrczo  于 2023-02-27  发布在  其他
关注(0)|答案(1)|浏览(119)

我有一个数据集,我需要将不同列中的某些值替换为NA。由于数据来自可能答案数量不同的调查,因此某些列中应该为NA的值发生了变化。我知道如何像这样更改值:

ayw <- ayw %>% 
  mutate(ExperienceWMentorSRP_01 = ifelse(ExperienceWMentorSRP_01 == 5, NA, ExperienceWMentorSRP_01))

或者像这样:

ayw$ExperienceWMentorSRP_01 <- replace(ayw$ExperienceWMentorSRP_01, ayw$ExperienceWMentorSRP_01 ==5, NA)

因此,在某些部分中,我将这行代码(下划线后面的数字不同)重复了十几次。我觉得有一种更有效的方法可以做到这一点,而不必每次都手动更改列名。
我试着做一个函数:

na.fun <- function(dataset, column, nanumber){
              dataset$column[dataset$column == nanumber] = NA
          }

na.fun(ayw, ExperienceWMentorSRP_01, 5)

但我得到了以下错误:
!分配的数据<lgl>必须与现有数据兼容。现有数据为155行。分配的数据为0行。
我想我可能走错了方向,我还是需要写n次,除非我让一个循环工作,我也试过这样做,就像这样:

for (row in mentorset){  #used `select() %>%` to make this subset(mentorset)so I didn't mess anything else
      for (col in row){
         ifelse(col == 5, NA, col)
      }
  }

但是当我每次尝试使用mentorset <-保存结果并打印结果时,结果是一个只有一个值的 Dataframe ,例如"4",我假设它保存了循环的最后一次迭代,这就是原因。
我该怎么解决这个问题呢?我最好还是手工写吧?

qpgpyjmq

qpgpyjmq1#

dataset$column正在查找一个按字面意义命名为column的列,而不是根据您传递给它的符号命名的列(请参见Dynamically select data frame columns using $ and a character value和[The difference between bracket [ ] and double bracket for accessing the elements of a list or dataframe](https://stackoverflow.com/q/1169456/3358272))。您将进入非标准求值(NSE)的领域,这是可以实现的,但通常充满了危险和困难的调试...如果您必须这样做,请查看tidyselect包和http://adv-r.had.co.nz/Computing-on-the-language.html
仅供参考,您收到的lgl错误是因为dataset$column返回NULL,如下所示

mtcars$DOES_NOT_EXISTS
# NULL

如果可以接受使用带引号的列名,如na.fun(ayw, "Experience", 5),那么尝试

na.fun <- function(dataset, column, nanumber){
  dataset[[ column ]][ dataset[[ column ]] == nanumber ] <- NA
  dataset
}

请注意,您的函数似乎希望通过副作用工作,希望更改将驻留在函数外部的数据中...除了少数例外,这种情况不会发生,R往往是写入时复制(非引用语义)。这意味着当您更改列中的值时,在na.fun内看到的dataset现在是调用外的ayw的 * 副本 *,因此ayw未改变。
为了解决这个问题,我们做两件事:返回函数 * 内部 * 的dataset(参见我上面的代码),并捕获函数 * 外部 * 的结果

ayw <- na.fun(ayw, "ExperienceWMentorSRP_01", 5)

(注意变量名两边的引号)

相关问题