使用向量对 Dataframe 中的变量进行重新编码

kpbpu008  于 2023-03-05  发布在  其他
关注(0)|答案(2)|浏览(103)

在最近的一个项目中,我有一个相当大的数据框架,我想用我之前定义的向量重新编程某些变量。
我知道有很多其他的方法来重新编码数据,但我想知道我是否可以使用向量,因为它似乎是一个优雅的解决方案。

df <- data.frame(
  A = c(1,2,2,1),
  B = c(1,1,1,2),
  C = c(2,2,1,2)
)

vector <- c(
  "A",
  "B"
)

考虑这个例子。这里我已经创建了一个向量,它由数据集中的2个名称组成。现在我可以使用这个向量来重新编程数据框吗?例如,我想将列'A'和'B'中的所有'1'改为'0'。
我试过这个:

df[df[,vector]==1] <- 0

然而,这段代码只工作,当我这样定义的向量:

vector <- c(
  "A",
  "B",
  "C"
)

因此,当它包含数据框中的所有变量时。
如果我使用相同的代码,但向量只包含'A'和'B',则会出现以下错误:

Error in `[<-.data.frame`(`*tmp*`, df[, vector] == 2, value = 1) : 
  unsupported matrix index in replacement

你有什么想法,这可能会如何工作?
此致

ebdffaop

ebdffaop1#

您可以从dplyr使用mutate(across())

mutate(df,across(all_of(vector),\(v) replace(v,v==1,0)))
eyh26e7m

eyh26e7m2#

一个基本的方法可以是用vector子集化df,然后在df[vector]==1中子集化这个。

df[,vector][df[,vector]==1] <- 0
#df[vector][df[vector]==1] <- 0 #Alternative

df
#  A B C
#1 0 0 2
#2 2 0 2
#3 2 0 1
#4 0 2 2

另一种方法是使用for循环。

for(i in vector) df[[i]][df[[i]]==1] <- 0
#for(i in vector) df[,i][df[,i]==1] <- 0 #Variant

基准

bench::mark(check=FALSE,
langtang = local({df <- dplyr::mutate(df,dplyr::across(all_of(vector),\(v) replace(v,v==1,0)))}),
"Maël" = local({df[, vector] <- replace(df[, vector], df[, vector] == 1, 0)}),
GKi = local({df[,vector][df[,vector]==1] <- 0}),
GKi2 = local(for(i in vector) df[,i][df[,i]==1] <- 0),
GKi3 = local(for(i in vector) df[[i]][df[[i]]==1] <- 0)
)
#  expression      min median itr/s…¹ mem_al…² gc/se…³ n_itr  n_gc total…⁴ result
#  <bch:expr> <bch:tm> <bch:>   <dbl> <bch:by>   <dbl> <int> <dbl> <bch:t> <list>
#1 langtang     2.66ms    3ms    299.   7.89KB    8.37   143     4   478ms <NULL>
#2 Maël       219.56µs  241µs   4017.     280B   12.3   1955     6   487ms <NULL>
#3 GKi        222.48µs  243µs   4013.     280B   12.3   1951     6   486ms <NULL>
#4 GKi2       106.96µs  116µs   8452.     280B   12.3   4119     6   487ms <NULL>
#5 GKi3        60.75µs   65µs  15217.     280B   14.4   7398     7   486ms <NULL>

for循环比其他 base 变体快约3倍,比 dplyr 变体快约50倍。所有 base 变体使用的内存都比 dplyr 变体少。

相关问题