我在R的数据框中有一列,其值为“-1”,“0”,“1”。我想分别用“否”,“也许”和"is"替换这些值。我将使用sub来做到这一点。

我可以编写一个条件函数,然后编写代码:

    df[col] <- lapply(df[col], conditional_function_substitution)

我也可以一次进行一次替换(三个例子中的第一个):
   df[col] <- lapply(df[col], sub, pattern = '-1', replacement = "no")

我想知道是否可以在一行中完成?就像是:
   df[col] <- lapply(df[col], sub, pattern = c('-1','0','1'), replacement = c('no','maybe','yes')

感谢您的见解!

最佳答案

通过将-1、0和1加2,您可以将索引放入所需结果的向量中:

c("no", "maybe", "yes")[dat + 2]
# [1] "no"    "yes"   "maybe" "yes"   "yes"   "no"

一个相关的选项可以利用match函数来找出索引:
c("no", "maybe", "yes")[match(dat, -1:1)]
# [1] "no"    "yes"   "maybe" "yes"   "yes"   "no"

或者,您可以使用命名向量进行重新编码:
unname(c("-1"="no", "0"="maybe", "1"="yes")[as.character(dat)])
# [1] "no"    "yes"   "maybe" "yes"   "yes"   "no"

您还可以使用嵌套的ifelse:
ifelse(dat == -1, "no", ifelse(dat == 0, "maybe", "yes"))
# [1] "no"    "yes"   "maybe" "yes"   "yes"   "no"

如果您不介意加载新程序包,则Recode程序包中的car函数将执行以下操作:
library(car)
Recode(dat, "-1='no'; 0='maybe'; 1='yes'")
# [1] "no"    "yes"   "maybe" "yes"   "yes"   "no"

数据:
dat <- c(-1, 1, 0, 1, 1, -1)

请注意,如果将dat存储为字符串,则除第一个以外的所有内容都将起作用;首先,您需要使用as.numeric(dat)

如果代码清晰是您的主要目标,则应选择最容易理解的代码-我个人将选择第二个或最后一个,但这是个人喜好。

如果您对代码速度感兴趣,则可以对解决方案进行基准测试。这是我介绍的五个选项的基准,还包括当前作为其他答案发布的其他两个解决方案,以长度为100k的随机向量为基准:
set.seed(144)
dat <- sample(c(-1, 0, 1), replace=TRUE, 100000)
opt1 <- function(dat) c("no", "maybe", "yes")[dat + 2]
opt2 <- function(dat) c("no", "maybe", "yes")[match(dat, -1:1)]
opt3 <- function(dat) unname(c("-1"="no", "0"="maybe", "1"="yes")[as.character(dat)])
opt4 <- function(dat) ifelse(dat == -1, "no", ifelse(dat == 0, "maybe", "yes"))
opt5 <- function(dat) Recode(dat, "-1='no'; 0='maybe'; 1='yes'")
AnandaMahto <- function(dat) factor(dat, levels = c(-1, 0, 1), labels = c("no", "maybe", "yes"))
hrbrmstr <- function(dat) sapply(as.character(dat), switch, `-1`="no", `0`="maybe", `1`="yes", USE.NAMES=FALSE)
library(microbenchmark)
microbenchmark(opt1(dat), opt2(dat), opt3(dat), opt4(dat), opt5(dat), AnandaMahto(dat), hrbrmstr(dat))
# Unit: milliseconds
#              expr        min         lq       mean     median         uq        max neval
#         opt1(dat)   1.513500   2.553022   2.763685   2.656010   2.837673   4.384149   100
#         opt2(dat)   2.153438   3.013502   3.251850   3.117058   3.269230   5.851234   100
#         opt3(dat)  59.716271  61.890470  64.978685  62.509046  63.723048 144.708757   100
#         opt4(dat)  62.934734  64.715815  71.181477  65.652195  71.123384 123.840577   100
#         opt5(dat)  82.976441  84.849147  89.071808  85.752429  88.473162 155.347273   100
#  AnandaMahto(dat)  57.267227  58.643889  60.508402  59.065642  60.368913  80.852157   100
#     hrbrmstr(dat) 137.883307 148.626496 158.051220 153.441243 162.594752 228.271336   100

前两个选项似乎比其他任何一个选项都快一个数量级,尽管矢量可能必须非常大,或者您需要多次重复该操作才能使该选项生效有所不同。

如@AnandaMahto所指出的,如果我们使用字符输入而不是数字输入,那么这些结果在质量上是不同的:
set.seed(144)
dat <- sample(c("-1", "0", "1"), replace=TRUE, 100000)
opt1 <- function(dat) c("no", "maybe", "yes")[as.numeric(dat) + 2]
opt2 <- function(dat) c("no", "maybe", "yes")[match(dat, -1:1)]
opt3 <- function(dat) unname(c("-1"="no", "0"="maybe", "1"="yes")[as.character(dat)])
opt4 <- function(dat) ifelse(dat == -1, "no", ifelse(dat == 0, "maybe", "yes"))
opt5 <- function(dat) Recode(dat, "-1='no'; 0='maybe'; 1='yes'")
AnandaMahto <- function(dat) factor(dat, levels = c(-1, 0, 1), labels = c("no", "maybe", "yes"))
hrbrmstr <- function(dat) sapply(dat, switch, `-1`="no", `0`="maybe", `1`="yes", USE.NAMES=FALSE)
library(microbenchmark)
microbenchmark(opt1(dat), opt2(dat), opt3(dat), opt4(dat), opt5(dat), AnandaMahto(dat), hrbrmstr(dat))
# Unit: milliseconds
#              expr       min        lq       mean     median         uq        max neval
#         opt1(dat)  8.397194  9.519075  10.784108   9.693706  10.163203   55.78417   100
#         opt2(dat)  2.281438  3.091418   4.231162   3.210794   3.436038   49.39879   100
#         opt3(dat)  3.606863  5.481115   6.466393   5.720282   6.344651   48.47924   100
#         opt4(dat) 66.819638 69.996704  74.596960  71.290522  73.404043  127.52415   100
#         opt5(dat) 32.897019 35.701401  38.488489  36.336489  38.950272   88.20915   100
#  AnandaMahto(dat)  1.329443  2.114504   2.824306   2.275736   2.493907   46.19333   100
#     hrbrmstr(dat) 81.898572 91.043729 154.331766 100.006203 141.425717 1594.17447   100

现在,@ AnandaMahto提出的factor解决方案是最快的,其次是使用match和命名向量查找进行向量索引。同样,所有运行时都足够快,以至于您需要一个大的向量或多次运行才能使这一切变得重要。

关于r - 一行R中的多个替换,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32170417/

10-11 11:04
查看更多