我正在创建两个数据框,然后将它们合并为第三个:
dat <- data.frame(code = c("A11", "B22", "C33"),
age = c(NA, NA, 12),
sex = c(NA, NA, 2),
more = c(7, 4, 9),
stringsAsFactors = FALSE)
age.and.sex <- read.table(textConnection("
code age sex
A11 15 2
B22 10 1
"), header = TRUE, stringsAsFactors = FALSE)
joined <- merge(dat, age.and.sex, by="code", all.x=TRUE)
joined
code age.x sex.x more age.y sex.y
1 A11 NA NA 7 15 2
2 B22 NA NA 4 10 1
3 C33 12 2 9 NA NA
现在,当我尝试将两个新列(“age.y”,“sex.y”)中的值复制到两个旧列(“age.x”,“sex.y”)中时,对于一列,但另一列我得到一个好奇的警告:
joined[is.na(joined$age.x)]$age.x <- joined$age.y
joined[is.na(joined$sex.x)]$sex.x <- joined$sex.y
Warning message:
In `[<-.data.frame`(`*tmp*`, is.na(joined$sex.x), value = list(code = c("A11", :
provided 5 variables to replace 4 variables
这里发生了什么?
答案 0 :(得分:4)
这两个专栏&#34;替换&#34;完全错了,但是让我们专注于第二个问题,因为第一个问题或多或少都是以无声方式失败了。
所以,让我们走过这条线
joined[is.na(joined$sex.x)]$sex.x <- joined$sex.y
一步一步。
首先从is.na()
作品的回归开始:
is.na(joined$sex.x)
[1] TRUE TRUE FALSE
长度为3的布尔矢量。我觉得可以吧。现在当我们基本上做joined[c(T,T,F)]
时会发生什么?
> joined[is.na(joined$sex.x)]
code age.x more age.y
1 A11 15 7 15
2 B22 10 4 10
3 C33 NA 9 NA
我打赌你不是没料到的! R认为你正在选择列,回收布尔向量并选择第1,2,4和5列。注意sex.x
根本不存在:
> joined[is.na(joined$sex.x)]$sex.x
NULL
此时应该完全清楚为什么你会收到警告。你试图分配给不存在的东西。
第一次尝试也失败了(它从NA
列中复制了.y
,这可能不是您想要的。但是你很幸运,你想要的专栏完全存在。
更一般地说,替换和子集化可能是一种脆弱的方法,你可能正在寻找coalesce函数。
答案 1 :(得分:1)
您为数据框的列编制了索引,并且您的索引是偶然的列数的倍数。看看你索引的内容:
> joined[is.na(joined$age.x)]
code age.x more age.y
1 A11 NA 7 15
2 B22 NA 4 10
3 C33 12 9 NA
我想您想要做的是以下内容:
joined[is.na(joined$age.x),]$age.x <- joined$age.y[is.na(joined$age.x)]
joined[is.na(joined$sex.x),]$sex.x <- joined$sex.y[is.na(joined$sex.x)]