【问题标题】:r for loop with names mutater for 名称发生变化的循环
【发布时间】:2016-06-05 13:02:00
【问题描述】:

我是新的 R 用户。我也知道以前有人问过并回答过类似的问题,但我无法弄清楚。目标是使用循环函数将一组变量中的 NA 替换为 0 值。显然,这是一个超级简单的循环函数,但我不知道为什么它没有做它应该做的事情。

两个额外的偏好,使用变量名(而不是列号)和使用 dplyr 的建议是首选。

提前感谢您的宝贵时间!

图书馆

library(plyr)
library(dplyr)

样本数据

y <- structure(list(pid = c(1002L, 1002L, 1002L, 1002L, 1002L, 1002L,1002L, 1002L, 1002L, 1002L), year = 1968:1977, weeks_hd_e = c(3,0, 50, 49, 50, 50, 50, 50, 50, 49), weeks_wf_e = c(4, 6, 0, 0,0, 0, 0, 0, 0, 0), weeks_hd_u = c(NA, NA, 0, 0, 0, 0, 0, 0, 0,0), weeks_hd = c(NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,NA_real_, NA_real_, NA_real_, NA_real_, NA_real_), weeks_wf_u = c(NA,NA, NA, NA, NA, NA, NA, NA, 0, NA), weeks_wf = c(NA_real_, NA_real_,NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,NA_real_)), .Names = c("pid", "year", "weeks_hd_e", "weeks_wf_e","weeks_hd_u", "weeks_hd", "weeks_wf_u", "weeks_wf"), row.names = c(NA,10L), class = "data.frame")

此命令有效

y <- mutate(y, i = ifelse(!is.na(i), i, 0))

这个循环没有

vars <- c("weeks_hd_e", "weeks_hd_u", "weeks_wf_e", "weeks_wf_u", "weeks_hd", "weeks_wf")
for (i in names(vars)) {
    y <- mutate(y, i = ifelse(!is.na(i), i, 0))
}

View(y)

【问题讨论】:

  • names(vars) 指的是对象名称,正如您在循环示例中给我们的那样,vars 中不存在这些名称。 (i in vars){etc} 是否解决了您的问题?
  • 嗯...不,不幸的是,这没有任何区别

标签: string loops for-loop dplyr na


【解决方案1】:

tidyr 包中的replace_na 命令完全符合您的要求。 像这样使用它:

install.packages("tidyr")
library(tidyr)

# your data
y <- structure(list(pid = c(1002L, 1002L, 1002L, 1002L, 1002L, 1002L,1002L, 1002L, 1002L, 1002L), year = 1968:1977, weeks_hd_e = c(3,0, 50, 49, 50, 50, 50, 50, 50, 49), weeks_wf_e = c(4, 6, 0, 0,0, 0, 0, 0, 0, 0), weeks_hd_u = c(NA, NA, 0, 0, 0, 0, 0, 0, 0,0), weeks_hd = c(NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,NA_real_, NA_real_, NA_real_, NA_real_, NA_real_), weeks_wf_u = c(NA,NA, NA, NA, NA, NA, NA, NA, 0, NA), weeks_wf = c(NA_real_, NA_real_,NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,NA_real_)), .Names = c("pid", "year", "weeks_hd_e", "weeks_wf_e","weeks_hd_u", "weeks_hd", "weeks_wf_u", "weeks_wf"), row.names = c(NA,10L), class = "data.frame")

# replacing NAs in your dataframe
# specify the variables you want to replace NAs in and the replacement in the `replace` = list argument
y <- replace_na(y, replace = list(weeks_hd_e = 0, weeks_hd_u = 0, weeks_wf_e = 0, weeks_wf_u = 0, weeks_hd = 0, weeks_wf = 0))

请注意,这符合您按名称指定变量的偏好,并且在替换方面更灵活,即您可以在同一命令中替换数字和字符变量中的 NA。

【讨论】:

    【解决方案2】:

    朋友给了我两个很好的答案:

    for (i in 1:length(vars)){
        y[vars[i]][is.na(y[vars[i]])] <- 0
    }
    

    y[, vars] <- apply(y[, vars], 2, function(x) ifelse(is.na(x), 0, x))
    

    【讨论】:

    • 如果没有循环,您是否要将除前两列之外的所有列都设为 0(如果它们是 NA)? y[-(1:2)][is.na(y[-(1:2)])] &lt;- 0
    猜你喜欢
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 2019-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多