我有一个数据框。其中一列具有要用作其他列名称条件的字符串值。例如,
df <- data.frame(
cond=c("a","b"),
aVal=c(1 , 2),
bVal=c(3 , 4)
)
我想逐行检查df中每一列的名称,如果colname不是以cond开头,那么我想将该列的值设置为0。 预期的输出将是。
# cond aVal bVal
# 1 a 1 0
# 2 b 0 4
我不确定如何使用R(最好是dplyr)来做到这一点。
答案 0 :(得分: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
数据
df <- data.frame(
cond=c("a","b"),
aVal=c(1 , 2),
bVal=c(3 , 4),
stringsAsFactors = FALSE
)
答案 1 :(得分:4)
这是一个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
上面的变化也是
df[-1] * (substr(matrix(names(df)[-1][row(df[-1])], 2, 2), 1, 1) ==
df$cond[col(df[-1])])
答案 2 :(得分:2)
library(tidyverse)
df <- data.frame(
cond=c("a","b"),
aVal=c(1 , 2),
bVal=c(3 , 4)
)
gather(df, col1, col2, -cond) %>%
as.tibble() %>%
filter(str_sub(col1, 1, 1) == cond) %>%
spread(col1, col2) %>%
mutate_at(vars(contains('Val')),
funs(replace(., is.na(.), 0)))
# A tibble: 2 x 3
cond aVal bVal
<fct> <dbl> <dbl>
1 a 1 0
2 b 0 4