采用所谓的“快捷方式”实际上是在 R 中做事的正确方法。但我确实认为手动循环有时是一种很好的练习。但是在您的“生产代码”中,即您想要依赖的代码中,请在适用时使用内置函数。
您的data.frame 只是缺少一个选项。其他一切都很好。问题在于,默认情况下,字符向量在data.frame 中作为factors 输入,当您尝试用factor 向量中的值替换值时,它会将其替换为该级别的基础数字索引。完整代码如下:
df1 <- data.frame(x = 1:3, y=letters[1:3], stringsAsFactors=FALSE)
df2 <- data.frame(x= rep(c(1,2,3),each=3))
for(i in 1:length(df2$x)){
df2$y[i]<- df1$y[which(df1$x == df2$x[i])]
}
df2
x y
1 1 a
2 1 a
3 1 a
4 2 b
5 2 b
6 2 b
7 3 c
8 3 c
9 3 c
有关stringsAsFactors 选项的更多信息,请参阅?data.frame
既然您似乎对学习感兴趣,那么您可能已经采用了一种调试方法。假设您的原始命令位于名为temp.R 的文件中。那么
> source('temp.R')
> ls()
[1] "df1" "df2" "i"
i 在 for 循环之后留下。让我们使用它,以便您的以下带有i 的命令将起作用。您可以将值重新分配给 i 以查看您的命令将为其他值提供什么。现在让我们开始分解代码,看看问题出在哪里。
> i
[1] 9
> which(df1$x == df2$x[i])
[1] 3
目前看起来不错。 3 是我们所期望的,对吧?
> df1$y[which(df1$x == df2$x[i])]
[1] c
Levels: a b c
在这里您需要认识到“哦,这是一个因素!”。每当您看到“级别”时,“因素”灯泡应该会在您的脑海中亮起。
在我们尝试替换之前让我们看看值,以确保您的其余代码没有意外修改它:
> df2$y[9]
[1] 3
看起来不错。我们知道替换后会发生什么,因此很明显分配出现了问题。让我们尝试一下,看看会发生什么:
> df2$y[9] <- as.factor("c")
> df2$y[9]
[1] 1
很明显有些不对劲。因此,我们将问题缩小到这里。现在我们需要回过头来找出为什么我们要用一个因子来替换。希望这将引导您获得data.frame 帮助。
这样的事情在R 中很烦人,但你只需要相信这样的行为是有原因的,一旦你在R 中学习更多编码以及更多R 的哲学,你就赢了不会有那么多这样的惊喜。祝你好运!