查找向量中存在的列并替换等于1的值

时间:2017-12-14 10:37:04

标签: r dataframe vector

我有一个类似于

的二进制数据集
     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

3 个答案:

答案 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()表示已复制了每个受影响的列。但只复制受影响的列,其他列未被触及。这与迄今为止发布的复制整个数据框的其他答案不同。