示例数据集:
library(tidyverse)
data <- data.frame(
l = c(NA, 2, NA, 4),
m = c(5, NA, 7, NA),
n = c(NA, 10, NA, NA),
o = c(6, 7, NA, 8),
y = c(2, 3, 4, 5))
因此,我需要替换每行中的第一个非“NA”值,当它在四行1到0中依次出现时。我想用一个新的值替换第一个非NA值,这个值是原始的第一个非NA值和y列中的值的乘积。
我尝试使用dplyr运行以下代码:
result <- data %>%
rowwise() %>%
mutate(
first_non_na_value = first(na.omit(c_across(l:o))),
replaced_value = ifelse(
!is.na(first_non_na_value),
first_non_na_value * y,
first_non_na_value
)
) %>%
ungroup()
然而,这给了我两个新的列,我不需要。我只希望新的“replaced_values”实际上替换每行中从左到右的l:o列中出现的第一个不是NA的值。我找不到一种方法来定义哪个列的值被替换,因为列将根据第一个(na.omit(c_across(l:o)))值出现的位置而改变。
预期结果应该如下所示:
result <- data.frame(
l = c(NA, 6, NA, 20),
m = c(10, NA, 28, NA),
n = c(NA, 10, NA, NA),
o = c(6, 7, NA, 8),
y = c(2, 3, 4, 5))
result
任何建议都将不胜感激
2条答案
按热度按时间ujv3wf0j1#
这里有一个相当迂回的tidyverse解决方案。我肯定还有更简洁优雅的。
1.将数据透视为长格式并按
y
分组1.按组查找第一个非NA值的索引(行
1.按组比较索引与行号,如果匹配,则计算乘积,否则保留原始值
1.选择所需的列并透视回宽格式
把这些放在一起:
结果:
vfwfrxfs2#
很高兴能在这里帮忙!我确信你可以用
*apply
函数而不是for循环来解决这个问题。可能sapply
会工作,但我不知道如何轻松地解决这个问题。此外,我无法让dplyr::coalesce
以与这里相同的方式工作。coalesce(l,m,n,o)
可以完成任务,但coalesce(l:o)
不能。如此快速和肮脏,对于几行,这里的输入略有不同。输入
结果