Как заменить каждый n-й элемент в столбце, если элемент имеет определенное значение в R

#r #dataframe

Вопрос:

Я хочу преобразовать следующий кадр данных без использования цикла, изменив значение » a «в 1-м и каждом 3-м элементе после на значение 5, если значение» b » в этой строке равно 1.

 df <- data.frame(a =c(2,2,2,2,2,2,2,2,2,2),b =  c(1,1,0,1,1,0,0,1,1,1))


df
   a b
1  2 1
2  2 1
3  2 0
4  2 1
5  2 1
6  2 0
7  2 0
8  2 1
9  2 1
10 2 1
 

преобразование df таким образом, что значение » a «при индексе 1,4,10 столбца a заменяется на 5, поскольку значение» b » равно 1 при индексе 1,4,10 в столбце b

  df
   a b
1  5 1
2  2 1
3  2 0
4  5 1
5  2 1
6  2 0
7  2 0
8  2 1
9  2 1
10 5 1
 

Я пытался использовать df[(seq(1,to=nrow(df),by=3))]==1 для проверки значения в » b «по этим конкретным индексам, но я не уверен, как включить его, чтобы изменить значение в» a » без использования цикла

Ответ №1:

Вы можете попробовать

 library(dplyr)

df %>%
  tibble::rownames_to_column() %>%
  rowwise %>%
  mutate(rowname = as.numeric(rowname),
         a = ifelse((rowname %% 3 == 1) amp;amp; b == 1 , 5, a)) %>%
  select(-rowname)

       a     b
   <dbl> <dbl>
 1     5     1
 2     2     1
 3     2     0
 4     5     1
 5     2     1
 6     2     0
 7     2     0
 8     2     1
 9     2     1
10     5     1
 

Ответ №2:

Для базового решения R,

 df[intersect(seq(1,nrow(df),by=3), which(df$b == 1)),'a'] <- 5
 

ВОЗВРАТ,

 > df
   a b
1  5 1
2  2 1
3  2 0
4  5 1
5  2 1
6  2 0
7  2 0
8  2 1
9  2 1
10 5 1
 

Ответ №3:

Вы можете сохранить dplyr решение в одной строке, используя расчет @Park.

 library(dplyr)

df <- data.frame(a =c(2,2,2,2,2,2,2,2,2,2),b =  c(1,1,0,1,1,0,0,1,1,1))

mutate(df, a = ifelse(row_number() %% 3 == 1 amp; b == 1, 5, a))
#>    a b
#> 1  5 1
#> 2  2 1
#> 3  2 0
#> 4  5 1
#> 5  2 1
#> 6  2 0
#> 7  2 0
#> 8  2 1
#> 9  2 1
#> 10 5 1
 

Ответ №4:

В базе R вы можете использовать

 df$a[seq_len(nrow(df)) %% 3 == 1 amp; df$b == 1] <- 5
df
#   a b
#1  5 1
#2  2 1
#3  2 0
#4  5 1
#5  2 1
#6  2 0
#7  2 0
#8  2 1
#9  2 1
#10 5 1