将数据框中的行替换为 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】:来自zoo
的na.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 > 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 到该值的行值循环,并为其重复其他列值