我想在不使用循环的情况下转换下面的数据帧,如果该行'b'的值为1,则将第1个和之后每3个元素中的'a'的值更改为值5。
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'在a列的索引1,4,10处的值被替换为5,因为'b'在b列的索引1,4,10处的值为1
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'中的值而不使用循环
你可以试试
library(dplyr)
df %>%
tibble::rownames_to_column() %>%
rowwise %>%
mutate(rowname = as.numeric(rowname),
a = ifelse((rowname %% 3 == 1) && 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
对于base 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
您可以使用@Park的计算将dplyr
解决方案保留为一行。
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 & 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
在base R中,可以使用
df$a[seq_len(nrow(df)) %% 3 == 1 & 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