我有一个数据框。其中一列具有字符串值,我想将其用作其他列名称的条件。例如,
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 来做到这一点。
这是一个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)
这是一个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)