我知道这里有几个类似的问题,但是似乎没有一个问题可以解决我遇到的确切问题。
set.seed(4)
df = data.frame(
Key = c("A", "B", "A", "D", "A"),
Val1 = rnorm(5),
Val2 = runif(5),
Val3 = 1:5
)
我想将其中Key ==“ A”的行的value列的值清零。通过a引用列名grep
:
cols = grep("Val", names(df), value = TRUE)
通常,在这种情况下,要实现我想要的功能,我将使用data.table
以下命令:
library(data.table)
df = as.data.table(df)
df[Key == "A", (cols) := 0]
所需的输出是这样的:
Key Val1 Val2 Val3
1 A 0.000000 0.00000000 0
2 B -1.383814 0.55925762 2
3 A 0.000000 0.00000000 0
4 D 1.437151 0.05632773 4
5 A 0.000000 0.00000000 0
但是,这一次我需要dplyr
在每个人都在使用的团队项目中使用它。我刚刚提供的数据是说明性的,我的真实数据是> 5m行,其中有16个值列需要更新。我唯一能想到的解决方案是这样使用mutate_at
:
df %>% mutate_at(.vars = vars(cols), .funs = function(x) ifelse(df$Key == "A", 0, x))
但是,这对我的真实数据而言似乎极其缓慢。我希望找到一个更优雅,更重要的是更快的解决方案。
我已经尝试了许多组合using map
,unquoting using !!
,using get
和:=
(烦人的可以被:=
in data.table掩盖)等。
6
这需要多长时间?df [df $ Key ==“ A”,cols] <-0。我可以看到它很慢,因为您正在调用ifelse并遍历列和行。
—
StupidWolf
StupidWolf,使用我的数据实际上非常快,同时非常紧凑和优雅。谢谢。如果您愿意,可以随意添加它作为答案。
—
LiviusI
好吧,我可以向您展示解决该问题的另一种解决方案
—
。– StupidWolf