我正在处理一个数据集,其中的分数是根据从临床记录中收集的数据计算出来的。在某些情况下,这些数据被忽略,因此分数无法计算,并记录为NA。
在某些情况下,我可以用以前的值替换安娜值。这种方法的局限性是:
如果分数为NA,检查前一个和下一个值是否为NA。如果前一个值和后一个值都不为NA,则插入这些分数的平均值。
如果分数为NA,请检查前一个值和下一个值是否为NA。如果只有前一个值不是NA,则将第一个NA值替换为前一个值。
如果序列中有两个或多个NA值,则仅替换第一个NA值,将其他NA值保留为NA。
我试过zoo::na函数。locf(),但这将不分青红皂白地替换所有NA,或限制替换大于许多NA的间隙。
我查看了整洁的填充,但文档中没有任何关于设置填充限制的内容。
对于以下数据:
ID,episode,score
1,1,1
1,2,1
1,3,1
1,4,NA
1,5,NA
1,6,NA
1,7,2
1,8,NA
1,9,4
1,10,NA
2,1,NA
2,2,2
2,3,3
2,4,4
2,5,NA
2,6,NA
2,7,3
2,8,NA
2,9,NA
2,10,NA
因此,我认为我在使用下面嵌套的ifelse变量时走上了正确的轨道,但我缺少关于函数的知识,我可以使用这些函数来将我的替换限制为特定数量的NA值
data <- data %>%
group_by(ID) %>%
arrange(episode) %>%
mutate(score = ifelse(is.na(score) & lag(!is.na(score)) & lead(!is.na(score)), average(sum(lag(score),lead(score))),
ifelse(is.na(score) & lag(!is.na(score)) & lead(is.na(score)), lag(score), ...) #And this is where I get stuck as I am unsure how to code for NA runs greater than 1
我的预期产出是:
ID,episode,score
1,1,1
1,2,1
1,3,1
1,4,*1
1,5,NA
1,6,NA
1,7,2
1,8,*3
1,9,4
1,10,*4
2,1,NA
2,2,2
2,3,3
2,4,4
2,5,*4
2,6,NA
2,7,3
2,8,*3
2,9,NA
2,10,NA
*s是为了清楚地说明值被复制到哪里。
一个选择是
library(dplyr)
data %>%
group_by(ID) %>%
group_by(grp = cumsum(lead(is.na(score) & !is.na(lead(score) &
!is.na(lag(score)) ))), add = TRUE) %>%
mutate(score1 = if(n() == 3 & is.na(score[2]) & sum(is.na(score))== 1)
replace(score, is.na(score), mean(score, na.rm = TRUE)) else score) %>%
ungroup %>%
select(-grp) %>%
mutate(score1 = coalesce(score1, lag(score1)))
# A tibble: 20 x 4
# ID episode score score1
# <int> <int> <int> <dbl>
# 1 1 1 1 1
# 2 1 2 1 1
# 3 1 3 1 1
# 4 1 4 NA 1
# 5 1 5 NA NA
# 6 1 6 NA NA
# 7 1 7 2 2
# 8 1 8 NA 3
# 9 1 9 4 4
#10 1 10 NA 4
#11 2 1 NA NA
#12 2 2 2 2
#13 2 3 3 3
#14 2 4 4 4
#15 2 5 NA 4
#16 2 6 NA NA
#17 2 7 3 3
#18 2 8 NA 3
#19 2 9 NA NA
#20 2 10 NA NA
如果我理解正确,每个 ID
的列分数
中只有两条规则可以替换 NA
值:
NA
)值的平均值。
替换为前面的(非 NA)值,并保留其他 NA
值。
这两个规则的实现归结为两个简单的< code>mutate()语句:首先,根据规则1,通过用< code>maxgap = 1L调用< code>zoo::na.approx()来替换所有单个< code>NA值。因此只有具有两个以上< code>NA值的序列保留下来(如果有的话)。最后,使用< code>if_else()和< code>lag()将每个< code>NA值替换为前面的值,以满足规则2。
library(dplyr)
data %>%
group_by(ID) %>%
mutate(new_score = zoo::na.approx(score, x = row_number(), maxgap = 1, na.rm = FALSE)) %>%
mutate(new_score = if_else(is.na(new_score), lag(new_score), new_score))
# A tibble: 20 x 4
# Groups: ID [2]
ID episode score new_score
<dbl> <dbl> <dbl> <dbl>
1 1 1 1 1
2 1 2 1 1
3 1 3 1 1
4 1 4 NA 1
5 1 5 NA NA
6 1 6 NA NA
7 1 7 2 2
8 1 8 NA 3
9 1 9 4 4
10 1 10 NA 4
11 2 1 NA NA
12 2 2 2 2
13 2 3 3 3
14 2 4 4 4
15 2 5 NA 4
16 2 6 NA NA
17 2 7 3 3
18 2 8 NA 3
19 2 9 NA NA
20 2 10 NA NA
请注意,这里创建了一个新列new_score
以进行比较。
用于替换分数
使用
data %>%
group_by(ID) %>%
mutate(score = zoo::na.approx(score, x = row_number(), maxgap = 1, na.rm = FALSE)) %>%
mutate(score = if_else(is.na(score), lag(score), score))
data <- readr::read_csv("ID,episode,score
1,1,1
1,2,1
1,3,1
1,4,NA
1,5,NA
1,6,NA
1,7,2
1,8,NA
1,9,4
1,10,NA
2,1,NA
2,2,2
2,3,3
2,4,4
2,5,NA
2,6,NA
2,7,3
2,8,NA
2,9,NA
2,10,NA")
从计算上讲,您可以将三个规则简化为一个复合条件:
如果< code >是. na(score[i]),则将每个< code>NA替换为其相邻元素的平均值
为此,您只需将 na.rm
= T 传递到 mean(),即 mean
(x[(i-1):(i 1)],na.rm = T),
您可以在 *apply
函数或 map
中使用,就像我在下面所做的那样。请注意,我还选择按索引位置引用和分配值,而不是使用前导
和滞后
,这会生成额外的向量。它可能不那么令人兴奋,但它也更有效率:
library(dplyr)
library(purrr)
mutate(df, score = map(seq_along(score),
~ ifelse(
is.na(score[.]) && !is.na(score[. - 1]),
mean(score[(. - 1):(. + 1)], na.rm = T),
score[.]
)))
#### OUTPUT ####
ID episode score
1 1 1 1
2 1 2 1
3 1 3 1
4 1 4 1
5 1 5 NA
6 1 6 NA
7 1 7 2
8 1 8 3
9 1 9 4
10 1 10 4
11 2 1 NA
12 2 2 2
13 2 3 3
14 2 4 4
15 2 5 4
16 2 6 NA
17 2 7 3
18 2 8 3
19 2 9 NA
20 2 10 NA
我有以下任务。有一根绳子。我必须按照6条规则在它中做替换,直到有可能在一个字符串中做一个替换。 我找到的解决办法就在下面。工作正常。问题是它的性能较低。我还可以如何根据多个规则进行替换?有什么算法吗? 附注。此任务来自codility站点。我的解决方案得到了100%的正确性和25%的性能。
我想创建一个新列,并用和替换和不丢失的值。 我想要的: 这就是我所尝试的: 看来第二行不正确。 有什么建议吗?
本文向大家介绍如何将NA替换为R数据帧中选定列的值?,包括了如何将NA替换为R数据帧中选定列的值?的使用技巧和注意事项,需要的朋友参考一下 在数据分析中,在数据框中查找某些NA值非常普遍,但如果包含NA值的列对分析无用,则所有NA值都不会产生问题。我们可以将所有NA值替换为0或将其他有用的列替换为其他值。 示例 请看以下数据帧- 将NA的连续列更改为零- 将NA的非连续列更改为零-
我有两个data.frames,每个都有数千行和几十列,都是通过合并几个csv文件创建的。data.frames正是我想要的。我还要补充一点,df1和df2有几列是共同的。唯一的问题是,在其中一个中,比如df1,对于某些列,有一些NAs(这是预期的/正常的)。好的一面是,我有NAs的相同列也出现在第二data.frame,比如df2,但没有NAs。我想做的是用df1同一列的值填充df2给定列中的N
使用ESLint是否可以忽略整个目录的一个特定规则? 在我的例子中,我想忽略为一个名为的目录