R dplyr:更改具有特定名称的列的行值

use*_*224 5 r dataframe dplyr

我有一个数据框。其中一列具有字符串值,我想将其用作其他列名称的条件。例如,

df <- data.frame(
  cond=c("a","b"),
  aVal=c(1  , 2),
  bVal=c(3  , 4)
)
Run Code Online (Sandbox Code Playgroud)

我想逐行检查 df 中每一列的名称,如果 colname 不以 cond 开头,那么我想将该列的值设置为 0。这里的预期输出将是。

#    cond aVal bVal
# 1    a    1    0
# 2    b    0    4
Run Code Online (Sandbox Code Playgroud)

我不知道如何用 R 最好用 dplyr 来做到这一点。

akr*_*run 5

这是一个base R选项

df[-1] <- df[-1] * t(apply(df, 1, function(x)  substr(names(x)[-1], 1, 1) == x[1]))
df
#   cond aVal bVal
#1    a    1    0
#2    b    0    4
Run Code Online (Sandbox Code Playgroud)

上述的变体也是

df[-1] * (substr(matrix(names(df)[-1][row(df[-1])], 2, 2), 1, 1) == 
               df$cond[col(df[-1])])
Run Code Online (Sandbox Code Playgroud)


www*_*www 4

这是一个tidyverse解决方案。请注意,我曾经stringsAsFactors = FALSE创建示例数据框来避免因子列。df2是最终的输出。

library(tidyverse)

df2 <- df %>%
  gather(Column, Value, -cond) %>%
  mutate(Column2 = str_sub(Column, 1, 1)) %>%
  mutate(Value = ifelse(map2_lgl(cond, Column2, ~str_detect(.y, .x)), Value, 0)) %>%
  select(-Column2) %>%
  spread(Column, Value)
df2
#   cond aVal bVal
# 1    a    1    0
# 2    b    0    4
Run Code Online (Sandbox Code Playgroud)

数据

df <- data.frame(
  cond=c("a","b"),
  aVal=c(1  , 2),
  bVal=c(3  , 4),
  stringsAsFactors = FALSE
)
Run Code Online (Sandbox Code Playgroud)