您应该可以在完全不使用for 循环的情况下做到这一点。
由于您没有提供任何数据,我将使用内置的iris 数据集。它的顶部看起来像:
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5.0 3.6 1.4 0.2 setosa
6 5.4 3.9 1.7 0.4 setosa
首先,我保存要分析的列:
columns <- names(iris)[1:4]
然后,对每一列使用mutate_at 以及该特定规则。在每个中,. 代表每列的向量。您的示例暗示每列的规则是相同的,但如果不是这种情况,您可能需要更多的灵活性。
mod_iris <-
iris %>%
mutate_at(columns, funs(ifelse(. > 5, 6, .))) %>%
mutate_at(columns, funs(ifelse(. < 1, 1, .)))
返回:
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 6.0 3.5 1.4 1 setosa
2 4.9 3.0 1.4 1 setosa
3 4.7 3.2 1.3 1 setosa
4 4.6 3.1 1.5 1 setosa
5 5.0 3.6 1.4 1 setosa
6 6.0 3.9 1.7 1 setosa
如果您愿意,您可以改为编写一个函数来对列进行所有更改。这也可以让您为每列设置不同的截止值。例如,您可能希望将数据的底部和顶部设置为等于该阈值(出于某种原因控制异常值),或者您可能知道每个变量都使用虚拟值作为占位符(并且该值列不同,但始终是最常见的值)。通过这种方式,您可以轻松添加任何感兴趣的任意规则,并且与将单独的规则链接在一起相比,它为您提供了更多的灵活性(例如,如果您使用平均值,则当您更改某些值时,平均值会发生变化)。
一个示例函数:
modColumns <- function(x){
botThresh <- quantile(x, 0.25)
topThresh <- quantile(x, 0.75)
dummyVal <- as.numeric(names(sort(table(x)))[1])
dummyReplace <- NA
x <- ifelse(x < botThresh, botThresh, x)
x <- ifelse(x > topThresh, topThresh, x)
x <- ifelse(x == dummyVal, dummyReplace, x)
return(x)
}
并在使用中:
iris %>%
mutate_at(columns, modColumns) %>%
head
返回:
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.3 1.6 0.3 setosa
2 5.1 3.0 1.6 0.3 setosa
3 5.1 3.2 1.6 0.3 setosa
4 5.1 3.1 1.6 0.3 setosa
5 5.1 3.3 1.6 0.3 setosa
6 5.4 3.3 1.7 0.4 setosa