将数据框中的行替换为 0,其前面的行值不同于 0

Posted

技术标签:

【中文标题】将数据框中的行替换为 0,其前面的行值不同于 0【英文标题】:Replace rows with 0s in dataframe with preceding row values diverse than 0 【发布时间】:2017-10-03 17:18:19 【问题描述】:

这是我的数据框的示例:

df = read.table(text = 'a  b
120 5
120 5
120 5
119 0
118 0
88 3
88 3
87 0  
10 3
10 3
10 3
7 4
6 0
5 0
4 0', header = TRUE)

我需要将 col b 中的 0 替换为前面的每个数字都不是 0。

这是我想要的输出:

 a  b
120 5
120 5
120 5
119 5
118 5
88 3
88 3
87 3  
10 3
10 3
10 3
7 4
6 4
5 4
4 4

直到现在我都尝试过:

df$b[df$b == 0] = (df$b == 0) - 1

但它不起作用。 谢谢

【问题讨论】:

【参考方案1】:

来自zoona.locf 可以提供帮助:

library(zoo)
#converting zeros to NA so that na.locf can get them
df$b[df$b == 0] <- NA
#using na.locf to replace NA with previous value
df$b <- na.locf(df$b)

输出:

> df
     a b
1  120 5
2  120 5
3  120 5
4  119 5
5  118 5
6   88 3
7   88 3
8   87 3
9   10 3
10  10 3
11  10 3
12   7 4
13   6 4
14   5 4
15   4 4

【讨论】:

【参考方案2】:

在简单的条件下执行此任务似乎相当困难,但您也可以使用小的 for 循环而不是加载包。

for (i in which(df$b==0)) 
  df$b[i] = df$b[i-1]

输出:

> df
     a b
1  120 5
2  120 5
3  120 5
4  119 5
5  118 5
6   88 3
7   88 3
8   87 3
9   10 3
10  10 3
11  10 3
12   7 4
13   6 4
14   5 4
15   4 4

我认为这对于大型 data.frames 可能会很慢

【讨论】:

对于此类任务,cum* 函数可能值得尝试。例如。这里df$b[cummax((df$b &gt; 0) * (1:nrow(df)))] 似乎是正确的。【参考方案3】:

这是使用rle 的基本 R 方法。

# get the run length encoding of variable
temp <- rle(df$b)
# fill in 0s with previous value
temp$values[temp$values == 0] <- temp$values[which(temp$values == 0) -1]
# replace variable
df$b <- inverse.rle(temp)

返回

df
     a b
1  120 5
2  120 5
3  120 5
4  119 5
5  118 5
6   88 3
7   88 3
8   87 3
9   10 3
10  10 3
11  10 3
12   7 4
13   6 4
14   5 4
15   4 4

请注意,如果向量的第一个元素为 0,替换行将引发错误。您可以通过创建一个排除它的向量来解决此问题。

例如

replacers <- which(temp$values == 0)
replacers <- replacers[replacers > 1]

【讨论】:

以上是关于将数据框中的行替换为 0,其前面的行值不同于 0的主要内容,如果未能解决你的问题,请参考以下文章

比较熊猫数据框中的行值

pyspark - 使用最大值为一列创建一个从 0 到该值的行值循环,并为其重复其他列值

用数据框的行值替换子列表中的第二项

如何在 WPF C# 中的 DataGrid 的 TextBoxes 中获取选定的行值

比较多行的行值 (R)

如何在 SQL SERVER 2017 SSMS 中用以前保存的行值替换行值