我有一个类似于
的二进制数据集 a b c d
r1 1 1 0 0
r2 0 1 1 0
r3 1 0 0 1
一个载体
V <- c("a", "c")
我想要一个命令来搜索字符串并更改这些列中的值。例如,将1更改为A.因此输出将为:
a b c d
r1 A 1 0 0
r2 0 1 A 0
r3 A 0 0 1
答案 0 :(得分:5)
这是一种矢量化的方法,
df[names(df) %in% V] <- replace(df[names(df) %in% V], df[names(df) %in% V] == 1, 'A')
#or avoid calling the %in% part 3 times by assigning it, i.e.
i1 <- names(df) %in% V
df[i1] <- replace(df[i1], df[i1] == 1, 'A')
#or a more simplified syntax, compliments of @Cath,
df[, V][df[, V]==1] <- "A"
给出,
a b c d r1 A 1 0 0 r2 0 1 A 0 r3 A 0 0 1
答案 1 :(得分:0)
dplyr
的解决方案:
library(dplyr)
V <- c("a", "c")
df %>%
mutate_at(V, ~replace(.x, .x == 1, 'A'))
# a b c d
# r1 A 1 0 0
# r2 0 1 A 0
# r3 A 0 0 1
mutate_at
获取一个data.frame和一个列名向量,并将指定的函数应用于每个列。
数据强>
df <- structure(list(a = c(1L, 0L, 1L), b = c(1L, 1L, 0L),
c = c(0L, 1L, 0L), d = c(0L, 0L, 1L)),
.Names = c("a", "b", "c", "d"),
class = "data.frame", row.names = c("r1", "r2", "r3"))
答案 2 :(得分:0)
如果左侧(LHS)和右侧(RHS)或相同类型,则data.table
可用于仅更新所选的&#34;单元&#34; 到位,即不复制整栏:
library(data.table)
setDT(df)
for (s in V) df[get(s) == 1L, (s) := 99L] # replacement value is of type integer
df[]
a b c d 1: 99 1 0 0 2: 0 1 99 0 3: 99 0 0 1
要验证每列中只选定的行是否已更新,我们可以使用以下命令检查更新前后每列的地址:
df[, lapply(.SD, address), .SDcols = V]
(此外,可以通过options(datatable.verbose = TRUE)
打开详细模式。)
如果LHS和RHS属于不同类型,则无论如何都需要进行类型转换。因此,需要更换整个列:
df[, (V) := lapply(.SD, function(x) replace(x, x == 1L, "A")), .SDcols = V]
df
a b c d 1: A 1 0 0 2: 0 1 A 0 3: A 0 0 1
使用address()
表示已复制了每个受影响的列。但只复制受影响的列,其他列未被触及。这与迄今为止发布的复制整个数据框的其他答案不同。