如何比较不等长度的df1和df2并在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])]
}

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

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

任何指导将受到高度赞赏.

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

您只是缺少data.frame的一个选项.其他一切都很好.问题是默认情况下,字符向量作为data.frame中的因子输入,当您尝试使用因子向量中的值替换值时,它将使用该级别的基础数字索引替换它.这是完整的代码:

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"

我在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哲学,你就不会有这么多的惊喜.祝好运!

点赞