用 R 中的其他整数替换数据框列中的整数?
Replace integers in a data frame column with other integers in R?
我想将仅包含 4 个数字的数据框中的向量替换为特定数字,如下所示
tt <- rep(c(1,2,3,4), each = 10)
df <- data.frame(tt)
我要替换1 = 10; 2 = 200, 3 = 458, 4 = -0.1
为了更正问题代码中的错误并提供更短的示例,我们在最后使用注释中的输入。这里有几种选择。在 (1) 中定义的 nos
也用于其他一些。没有使用包。
1) 索引 由于输入是 1 到 4,我们可以使用索引来获取结果。这可能是最简单的解决方案,因为 tt 的原始值在 1:4.
中
nos <- c(10, 200, 458, -0.1)
transform(df, tt = nos[tt])
## tt
## 1 10.0
## 2 10.0
## 3 200.0
## 4 200.0
## 5 458.0
## 6 458.0
## 7 -0.1
## 8 -0.1
1a) 如果输入不一定在 1:4 那么我们可以使用这个泛化
transform(df, tt = nos[match(tt, 1:4)])
2)算术另一种方法是用算术:
transform(df, tt = 10 * (tt == 1) +
200 * (tt == 2) +
458 * (tt == 3) +
-0.1 * (tt == 4))
3) outer/matrix 乘法 这也可以:
transform(df, tt = c(outer(tt, 1:4, `==`) %*% nos))
3a) 除了我们使用model.matrix而不是outer.
之外,这是相同的
transform(df, tt = c(model.matrix(~ factor(tt) + 0, df) %*% nos))
4) factor 因子的水平是1:4,对应的标签由nos
定义。使用格式提取标签,然后将它们转换为数字。
transform(df, tt = as.numeric(format(factor(tt, levels = 1:4, labels = nos))))
4a) 或作为管道
transform(df, tt = tt |>
factor(levels = 1:4, labels = nos) |>
format() |>
as.numeric())
5) 循环 我们可以使用一个简单的循环。最后去掉 i 是为了不做成一列。
within(df, { for(i in 1:4) tt[tt == i] <- nos[i]; i <- NULL })
6) Reduce 这有点类似于(5)但是使用Reduce实现了循环。
fun <- function(tt, i) replace(tt, tt == i, nos[i])
transform(df, tt = Reduce(fun, init = tt, 1:4))
备注
df <- data.frame(tt = c(1, 1, 2, 2, 3, 3, 4, 4))
您可以使用 dplyr
中的 recode
。请注意,旧值被写为字符。并且新值是整数,因为原始列是整数:
library(tidyverse):
df %>%
mutate(tt = recode(tt, '1'= 10, '2' = 200, '3' = 458, '4' = -0.1))
tt
1 10.0
2 10.0
3 200.0
4 200.0
5 458.0
6 458.0
7 -0.1
8 -0.1
我想将仅包含 4 个数字的数据框中的向量替换为特定数字,如下所示
tt <- rep(c(1,2,3,4), each = 10)
df <- data.frame(tt)
我要替换1 = 10; 2 = 200, 3 = 458, 4 = -0.1
为了更正问题代码中的错误并提供更短的示例,我们在最后使用注释中的输入。这里有几种选择。在 (1) 中定义的 nos
也用于其他一些。没有使用包。
1) 索引 由于输入是 1 到 4,我们可以使用索引来获取结果。这可能是最简单的解决方案,因为 tt 的原始值在 1:4.
中nos <- c(10, 200, 458, -0.1)
transform(df, tt = nos[tt])
## tt
## 1 10.0
## 2 10.0
## 3 200.0
## 4 200.0
## 5 458.0
## 6 458.0
## 7 -0.1
## 8 -0.1
1a) 如果输入不一定在 1:4 那么我们可以使用这个泛化
transform(df, tt = nos[match(tt, 1:4)])
2)算术另一种方法是用算术:
transform(df, tt = 10 * (tt == 1) +
200 * (tt == 2) +
458 * (tt == 3) +
-0.1 * (tt == 4))
3) outer/matrix 乘法 这也可以:
transform(df, tt = c(outer(tt, 1:4, `==`) %*% nos))
3a) 除了我们使用model.matrix而不是outer.
之外,这是相同的transform(df, tt = c(model.matrix(~ factor(tt) + 0, df) %*% nos))
4) factor 因子的水平是1:4,对应的标签由nos
定义。使用格式提取标签,然后将它们转换为数字。
transform(df, tt = as.numeric(format(factor(tt, levels = 1:4, labels = nos))))
4a) 或作为管道
transform(df, tt = tt |>
factor(levels = 1:4, labels = nos) |>
format() |>
as.numeric())
5) 循环 我们可以使用一个简单的循环。最后去掉 i 是为了不做成一列。
within(df, { for(i in 1:4) tt[tt == i] <- nos[i]; i <- NULL })
6) Reduce 这有点类似于(5)但是使用Reduce实现了循环。
fun <- function(tt, i) replace(tt, tt == i, nos[i])
transform(df, tt = Reduce(fun, init = tt, 1:4))
备注
df <- data.frame(tt = c(1, 1, 2, 2, 3, 3, 4, 4))
您可以使用 dplyr
中的 recode
。请注意,旧值被写为字符。并且新值是整数,因为原始列是整数:
library(tidyverse):
df %>%
mutate(tt = recode(tt, '1'= 10, '2' = 200, '3' = 458, '4' = -0.1))
tt
1 10.0
2 10.0
3 200.0
4 200.0
5 458.0
6 458.0
7 -0.1
8 -0.1