在跨多列的数据框上使用 if else

mlc*_*cyo 2 for-loop if-statement r dataframe

我有一个包含样本是否可行的描述符的大型样本数据集 - 它看起来(有点)像这样,其中“desc”是描述列,“blank”表示样本不可行:

     desc        x        y        z
1   blank 4.529976 5.297952 5.581013
2   blank 5.906855 4.557389 4.901660
3  sample 4.322014 4.798248 4.995959
4  sample 3.997565 5.975604 7.160871
5   blank 4.898922 7.666193 5.551385
6   blank 5.667884 5.195825 5.232072
7   blank 5.524773 6.726074 4.767475
8  sample 4.382937 5.926217 5.203737
9  sample 4.976908 3.079191 4.614121
10  blank 4.572954 4.772373 6.077195
Run Code Online (Sandbox Code Playgroud)

我想使用 if else 语句将具有不可用数据的行设置为 NA。最终的数据集应如下所示:

     desc        x        y        z
1   blank       NA       NA       NA
2   blank       NA       NA       NA
3  sample 4.322014 4.798248 4.995959
4  sample 3.997565 5.975604 7.160871
5   blank       NA       NA       NA
6   blank       NA       NA       NA
7   blank       NA       NA       NA
8  sample 4.382937 5.926217 5.203737
9  sample 4.976908 3.079191 4.614121
10  blank       NA       NA       NA 
Run Code Online (Sandbox Code Playgroud)

我尝试了 for 循环,但我无法让 for 循环更改一个循环中的所有列。我的真实数据集有 40 列,所以我宁愿不必在单独的循环中处理它!这是一次更改一列的代码:

for(i in 1:length(desc)){
    if(dat$desc[i] =="blank"){
    dat$x[i] <- NA
    } 
    else {
    dat$x[i] <- dat$x[i]
    }
}
Run Code Online (Sandbox Code Playgroud)

我用这个脚本制作了示例数据:

desc <- c("blank", "blank", "sample", "sample", "blank", "blank", "blank",    "sample", "sample", "blank")
x <-  rnorm(10, mean=5, sd=1)
y <-  rnorm(10, mean=5, sd=1)
z <-  rnorm(10, mean=5, sd=1)

dat <- data.frame(desc,x,y,z)
Run Code Online (Sandbox Code Playgroud)

抱歉,如果这是一个基本问题,我已经花了一个上午的时间查看论坛,但找不到解决方案。

任何帮助深表感谢!

jen*_*yan 8

这是另一个 dplyr 解决方案,带有一个小的自定义函数和mutate_each().

library(dplyr)

f <- function(x) if_else(dat$desc == "blank", NA_real_, x)
dat %>% 
  mutate_each(funs(f), -desc)
#>      desc        x        y        z
#> 1   blank       NA       NA       NA
#> 2   blank       NA       NA       NA
#> 3  sample 3.624941 6.430955 5.486632
#> 4  sample 3.236359 4.935453 4.319202
#> 5   blank       NA       NA       NA
#> 6   blank       NA       NA       NA
#> 7   blank       NA       NA       NA
#> 8  sample 5.058725 6.751650 4.750529
#> 9  sample 5.837206 4.323562 4.914780
#> 10  blank       NA       NA       NA
Run Code Online (Sandbox Code Playgroud)


dww*_*dww 7

对于您的示例数据集,这将起作用;

选项 1,命名要更改的列:

dat[which(dat$desc == "blank"), c("x", "y", "z")] <- NA
Run Code Online (Sandbox Code Playgroud)

在你有 40 列的实际数据中,如果你只是想将最后 39 列设置为 NA,那么下面的可能比命名每一列要更改更简单;

选项 2,使用范围选择列:

dat[which(dat$desc == "blank"), 2:40] <- NA
Run Code Online (Sandbox Code Playgroud)

选项 3,排除第一列:

dat[which(dat$desc == "blank"), -1] <- NA
Run Code Online (Sandbox Code Playgroud)

选项 4,排除命名列:

dat[which(dat$desc == "blank"), !names(dat) %in% "desc"] <- NA
Run Code Online (Sandbox Code Playgroud)

如您所见,有很多方法可以执行此类操作(这远非完整列表),了解这些选项中的每一个的工作原理将有助于您更好地理解该语言。