将数据框中某一列的所有负值改为零。

8
在R中,我该如何将数据框中某一列的所有负值更改为零?是否有一个简单的函数可以与apply()一起使用来完成此任务?或者,如何编写循环来实现这个目标?非常感谢!
4个回答

12
你可以使用一个ifelse命令:
df$column <- ifelse(df$column < 0, 0, df$column)

或者像评论中@Jilber所说的那样:

df$column[df$column < 0] <- 0
within(df, column[column<0] <- 0)

6
一个更简短的版本是 df$column[df$column < 0] <- 0 或者 within(df, column[column<0] <- 0)?只是为了避免使用 ifelse - Jilber Urbina
非常感谢@Jaap!我真的很新到R语言,之前不知道这个函数。 - Runner

1

也许更容易使用Jaap建议的ifelse语句或者索引,但我发现这种方法很有趣(利用布尔代数)。

> dat<-data.frame(c1=sample(c(10,-10),10,T))
> dat
    c1
1  -10
2   10
3  -10
4   10
5   10
6   10
7  -10
8   10
9   10
10 -10
> dat<-within(dat, c1<-c1*(c1>0))
> dat
   c1
1   0
2  10
3   0
4  10
5  10
6  10
7   0
8  10
9  10
10  0

它在这种情况下还可以比使用ifelse/索引提供一些性能提升(当然,这样做远不如灵活,因此在某些情况下可能不值得获得性能提升)。
> dat<-data.frame(c1=sample(c(10,-10),1e6,T))
> system.time(within(dat, c1<-ifelse(c1 < 0, 0, c1)))
   user  system elapsed
  0.382   0.000   0.386
> system.time(dat[dat$c1 < 0,] <- 0)
   user  system elapsed
   0.08    0.00    0.08
> system.time(within(dat, c1<-c1*(c1>0)))
   user  system elapsed
  0.043   0.000   0.044
> dat1<-within(dat, c1<-ifelse(c1 < 0, 0, c1))
> dat2<-within(dat, c1<-c1*(c1>0))
> identical(dat1,dat2)
[1] TRUE

1
使用 dplyr
library(dplyr)

> df <- tibble(c1 = sample(c(10, -10), 10, T))
> df
# A tibble: 10 x 1
      c1
   <dbl>
 1    10
 2   -10
 3    10
 4   -10
 5   -10
 6    10
 7    10
 8   -10
 9   -10
10    10

> df %>% mutate(c1 = if_else(c1 < 0, 0, c1))
# A tibble: 10 x 1
      c1
   <dbl>
 1    10
 2     0
 3    10
 4     0
 5     0
 6    10
 7    10
 8     0
 9     0
10    10

0

您可以使用以下方式快速处理整个数据框

dat[dat < 0] = 0

这个问题特定于单个/特定列。所以可能是 dat$column[dat$column < 0] <- 0(已在接受的答案中涵盖)。 - Werner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接