替换数据框列中的序列

时间:2018-03-16 13:57:39

标签: r dataframe replace

我在R中有一个看起来像这样的数据框:

A | B
0   0
1   0
0   0
0   0
0   1
0   1
1   0
1   0
1   0

我现在想要替换多个" 1"的所有序列。在列中只有第一个" 1"保留,其他人被" 0"替换,所以结果看起来像这样

A | B
0   0
1   0
0   0
0   0
0   1
0   0
1   0
0   0
0   0

我希望你明白我的意思(英语不是我的母语,特别是R - "词汇"有点难,这可能就是为什么我无法找到解决办法的原因google搜索)。提前谢谢!

5 个答案:

答案 0 :(得分:0)

试试这个解决方案:

输入数据

df<-data.frame( 
 A=c(1,0,0,0,0,0,1,1,1,0),
 B=c(1,1,0,1,0,0,1,1,0,0))


 f<-function(X)
 {
  return(as.numeric((diff(c(0,X)))>0))
 }

您的输出

     data.frame(lapply(df,f))
       A B
    1  1 1
    2  0 0
    3  0 0
    4  0 1
    5  0 0
    6  0 0
    7  1 1
    8  0 0
    9  0 0
    10 0 0

答案 1 :(得分:0)

您可以使用ave并根据值的差异创建组,以将连续的1和0捕获为不同的组,并将重复项替换为0,即

df[] <- lapply(df, function(i)ave(i, cumsum(c(1, diff(i) != 0)), 
                                FUN = function(i) replace(i, duplicated(i), 0)))

给出,

  A B
1 0 0
2 1 0
3 0 0
4 0 0
5 0 1
6 0 0
7 1 0
8 0 0
9 0 0

答案 2 :(得分:0)

以下是rleid

的选项
library(data.table)
df1[] <- lapply(df1, function(x) +(x==1& !ave(x, rleid(x), FUN = duplicated)))

df1
#  A B
#1 0 0
#2 1 0
#3 0 0
#4 0 0
#5 0 1
#6 0 0
#7 1 0
#8 0 0
#9 0 0

&LT;

答案 3 :(得分:0)

这是一个简单的答案:

> df * rbind(c(0,0), sapply(df, diff))
  A B
1 0 0
2 1 0
3 0 0
4 0 0
5 0 1
6 0 0
7 1 0
8 0 0
9 0 0

这利用了以下事实:原始数据中的所有不需要的1都将0diff函数一起使用。

答案 4 :(得分:0)

这是一种更实用的方法。虽然,我在这里找到了较短的答案,但了解可能的实施情况很好:

# helper function
make_zero <- function(val)
{
    get_index <- c()
    for(i in seq(val))
    {
        if(val[i] == 1) get_index <- c(get_index, i)
        else if (val[i] != 1) get_index <- c()

        if(all(diff(get_index)) == 1)
        {
            val[get_index[-1]] <- 0
        }
    }
    # set values as 0
    return (val)
}

df <- sapply(df, make_zero)
head(df)

     A B
 [1,] 0 0
 [2,] 1 0
 [3,] 0 0
 [4,] 0 0
 [5,] 0 1
 [6,] 0 0
 [7,] 1 0
 [8,] 0 0
 [9,] 0 0

说明:
1.我们在get_index中保存连续1的索引。
2.接下来,我们检查索引之间的差异是否为1 3.如果找到,我们更新列中的值。