我正在寻找一种方法,该方法使用从同一行但从同一数据的不同列中获取的值来填充一列,我希望从中获取值的列是随机选择的。
我的数据如下:
sic.code.1 sic.code2 sic.code3 sic.code4
7361 6211 NA NA
6719 NA NA NA
2329 NA 5065 5411
2869 3674 6282 NA
6282 6282 NA NA
6282 NA NA NA
我想创建一个新列“ sic.code.final”,其中每一行都用唯一的非na值填充(例如,第二行中的6719或第6行中的6282),或者在其他“ sic.code”列中的其他非na值中,应使用从其中之一获取的值(随机选择)填充该值。
我期望数据的可能实现之一可能是:
sic.code.1 sic.code2 sic.code3 sic.code4 sic.code.final
7361 6211 NA NA 6211
6719 NA NA NA 6719
2329 5065 5411 NA 2329
2869 3674 6282 NA 3674
6282 6282 NA NA 6282
6282 NA NA NA 6282
任何帮助将不胜感激!
编辑
在我的数据中,有些行的所有列都具有NA:
sic.code.1 sic.code2 sic.code3 sic.code4
7361 6211 NA NA
6719 NA NA NA
2329 NA 5065 5411
2869 3674 6282 NA
6282 6282 NA NA
NA NA NA NA
答案 0 :(得分:1)
这就是我在基地里要做的
df <- data.frame(sic.code.1 = 1:6,
sic.code2 = c(7, NA, NA, 8, 9, NA),
sic.code3 = c(NA, NA, 10, 1, NA, NA),
sic.code4 = c(NA, NA, 12, NA, NA, NA))
cbind(df, sic.code.final = apply(df, 1, function(x) sample(rep(x[!is.na(x)], 2), 1)))
答案 1 :(得分:1)
另一种基本方法
set.seed(42)
df[, "final"] <- df[cbind(1:nrow(df),
max.col(!is.na(df), ties.method = "random"))]
结果
df
# sic.code.1 sic.code2 sic.code3 sic.code4 final
#1 1 7 NA NA 1
#2 2 NA NA NA 2
#3 3 12 10 NA 10
#4 4 8 1 NA 4
#5 5 9 NA NA 5
#6 6 NA NA NA 6
此选项使用ties.method
的{{1}}参数。 (默认值为max.col
,因此您实际上不需要输入)
"random"
为每一行返回非max.col(!is.na(df), ties.method = "random")
值的列索引。然后NA
从您的数据中提取这些值。
数据
感谢@JamesBonkowski
cbind(1:nrow(df), ...
答案 2 :(得分:0)
另一种基本方法...我认为它与James Bonkowski的区别在于对行的更健壮的处理,其中只有1个值不是NA。同样,以某种方式将fun
的定义与其应用程序分开,对于理解代码和代码重用似乎很有用。
考虑从向量采样的问题(在我们的用例中为一行)。有两个挑战。首先,我们只想采样非NA值。第二个是sample()
对待长度大于1的向量与长度为1的向量不同,如?sample
所述。以下功能解决了这两个问题...
fun = function(x) {
x = x[!is.na(x)]
x[sample(length(x), 1)]
}
不幸的是,当向量包含所有NA时,它将返回长度为0的向量,而不是长度为1的向量,例如
> fun(NA)
logical(0)
可能不是一个特别优雅的变化
fun = function(x) {
x = x[!is.na(x)]
if (length(x)) {
x[sample(length(x), 1)]
} else NA
}
那么眼前问题的应用就是apply()
和cbind()
的简单应用
cbind(df, final = apply(df, 1, fun))
尝试使用“ tidyverse”方法来应用它令人沮丧,
df %>% rowwise() %>% mutate(final = fun(.))
可以,但是不会。