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

时间:2018-08-24 19:24:59

标签: r dataframe dplyr

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

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)来做到这一点。

3 个答案:

答案 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