我需要连续计算非NA值之间的差异。例如,如果仅在点a,c和e处存在值,并且b和d中的值均为NA,则我需要计算c与a,e和c之间的差,并保留b与a和之间的差。 d和c为空白。 d1是b中的非NA值和最接近左侧的非NA值(必须是a中的非NA值)之间的差。 d2是c中的非NA值与最接近左侧的非NA值之间的差。 d3是d中的非NA值和最接近左侧的非NA值之间的差。 d4是e中的非NA值和最接近左侧的非NA值之间的差。
我认为我缺少一些在这种情况下可以使用的R函数。我尝试编写许多ifelse条件,这些条件说明了前面的数据点是NA,事实证明这是一个很长的ifelse语句。
df$d1<-ifelse(!is.na(df$a and !is.na(df$b), df$b-df$a)
但是我离得越远,ifelse语句就越复杂。
我也试过写
df$d1<-(!is.na(df$b))-(!is.na(df$a))
结果不是差异,而是第一个数据点是否为NA(在d1列中得到0、1,-1)。
这是我原始数据库的结构:
```a<-c(10, 20, NA, 40, 50, 60)
b<-c(5, NA, 6, 7, NA, 8)
c<-c(NA, 4, 5, NA, 7, 8)
d<-c(NA, 9, 8, 7, 6, 5)
e<-c(3, 4, NA, 5, 6, 7)
df<-data.frame(a, b, c, d, e)```
这就是我需要显示结果的方式:
```d1<-c('-5','' ,'' , '-33','', '-52')
d2<-c('', '-16', '-1', '', '-43', '0')
d3<-c('', '5', '3', '0', '-1', '-3')
d4<-c('-2', '-5', '', '-2', '0', '2')
df1<-data.frame(d1, d2, d3, d4)```
答案 0 :(得分:1)
这里是一个选项。我们使用pmap
(或使用apply
中的base R
和MARGIN = 1
遍历行),获得相邻非NA元素('i1 '),以正确的顺序绑定行(diff
,pmap_dfr
列名称和select
列
rename
注意:默认情况下,缺少的元素将用library(dplyr)
library(stringr)
library(purrr)
pmap_dfr(df, ~ {
x <- c(...)
i1 <- !is.na(x)
diff(x[i1]) %>%
as.list}) %>%
select(sort(names(.))) %>%
rename_all(~ str_c('d', seq_along(.)))
# A tibble: 6 x 4
# d1 d2 d3 d4
# <dbl> <dbl> <dbl> <dbl>
#1 -5 NA NA -2
#2 NA -16 5 -5
#3 NA -1 3 NA
#4 -33 NA 0 -2
#5 NA -43 -1 0
#6 -52 0 -3 2
填充。最好不要使用空字符串(NA
),因为它将列类型从""
更改为numeric
如果只有character
行,请找到
NA