如何比较不等长度的df1和df2并在R中赋值

时间:2011-12-04 09:45:51

标签: r

这些是df1和df2的定义:

df1 <- data.frame(x = 1:3, y=letters[1:3])
df2 <- data.frame(x= rep(c(1,2,3),each=3))

我想将df1中的列y的值分配给df2中的列y,其中df1的列x中的值等于df2的列x中的值。如上所示,df1和df2长度不等。

for(i in 1:length(df2$x)){
        df2$y[i]<- df1$y[which(df1$x == df2$x[i])]
}

我不是在寻找捷径来做这件事(请不要内置功能)。我想以正确的方式学习它。

我的逻辑是否正确? 如果这是为什么这不起作用?

任何指导都将受到高度赞赏。

1 个答案:

答案 0 :(得分:2)

接受你所说的“快捷方式”实际上是在R中做事的正确方法。但我确实认为手动循环有时是一个很好的练习。但是在您的“生产代码”中,即您想要依赖的代码,请在适用时使用内置函数。

您只是遗漏了data.frame的一个选项。其他一切都很好。问题是默认情况下,字符向量在factors中输入为data.frame,当您尝试使用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

有关?data.frame选项

的详情,请参阅stringsAsFactors

由于您似乎对学习感兴趣,因此您可以采用以下方式进行调试。假设您的原始命令位于名为temp.R的文件中。然后

> source('temp.R')
> ls()
[1] "df1" "df2" "i"
在for循环之后,

i被遗留下来。让我们使用它,以便您的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

在这里你需要认识到“哦,这是一个因素!”。每当你看到“Levels”时,“factor”灯泡应该点亮你的脑袋。

让我们在尝试替换之前看到值,以确保代码的其余部分不会意外地修改它:

> df2$y[9]
[1] 3

看起来不错。我们知道更换后会发生什么,所以这项任务明显出现问题。让我们试试看看会发生什么:

> df2$y[9] <- as.factor("c")
> df2$y[9]
[1] 1
显然有些事情是错的。因此,我们将问题缩小到了这里。现在我们需要回过头来找出我们为什么要用一个因素取而代之。希望这会引导您进入data.frame帮助。

这样的事情在R中很烦人,但你必须要相信有这样的行为的理由,并且一旦你在R及更多R中学习更多编码的哲学,你不会有这么多的惊喜。祝你好运!