【问题标题】:How do I assign value to a row in a dataframe based on another in r?如何根据 r 中的另一行为数据框中的一行赋值?
【发布时间】:2016-06-12 21:50:16
【问题描述】:

我正在查看不同样本中捕获的蝴蝶的数据。我的问题是用于同一物种的“名称”(数字)不一致。每个物种都被分配了一个编号来识别它们。

我有两个数据框,第一个是每个物种“mydata”的计数数据集,但其中的每个物种都被分配了多个 ID,而不仅仅是一个正确的 ID。所以两个不同的数字可能指的是同一个物种,我需要确保我的名字是标准化的。

IDs <- c(10,8,3,42,7,23,42,2)
sample1 <- c(0,0,2,0,3,0,0,2)
sample2 <- c(0,1,0,2,4,0,3,1)
sample3 <- c(0,1,1,0,2,0,3,1)
sample4 <- c(0,2,0,2,0,1,2,1)
sample5 <- c(3,1,0,0,1,0,0,1)
mydata <- cbind(IDs,sample1,sample2,sample3,sample4,sample5)

我有第二个数据库用作参考,“specieslist”,其中包含正确的 ID,以及可能已使用的所有替代 ID。

ID1 <- c(10,34,20,2,7,38)
ID2 <- c(22,3,42,NA,6,23)
ID3 <- c(NA,8,NA,NA,1,NA)
correct.ID <- c(10,3,20,2,1,23)
specieslist <- cbind(ID1,ID2,ID3,correct.ID)
splist <- replace(specieslist,is.na(specieslist),0)

我想搜索 specieslist 以找出应该使用的数字 mydata,并将正确的 ID 分配给 mydata 中的新列。

我一直在尝试创建一个循环来找出 specieslist 的哪一行包含 mydata 中的值,然后选择 correctID 中的值该行的 列。

corr.sp <- c(NULL)
rws <- length(mydata[,1])
for(s in 1:rws){
  dat <- as.character(mydata[s,1])
  pos <- which(splist==dat, arr.ind=TRUE)
  ind <- pos[1,1]
  corr <- as.matrix(splist[ind,4])
  corr.sp <- c(corr.sp,corr)
}

mydata.corrsps <- cbind(mydata,corr.sp)

我期望 corr.spmydata.corrsps 看起来像这样:

corr.sp <- c(10,3,3,20,1,23,20,2)
mydata.corrsps <- cbind(mydata,corr.sp)

此演示代码似乎有效,但在我的一些真实数据中,当我运行循环时出现错误,提示我的行索引 (pos[1,1]) 超出范围 -在搜索该数据集中未找到的物种行之前,我遇到过此错误,但我已经完成并删除了任何适用的行,将文件保存为 csv 并重新导入以避免行错误-index 混淆(在 r 中设置子集时似乎发生在数据上)。我还检查了 pos(1,1) 的最大值是否不超过可供选择的行数,并且我检查了它搜索的所有值是否都存在于数据中。

如果有人能提出一种更好的方法来做我没有成功的事情,或者指出我哪里出错了,我将不胜感激。

【问题讨论】:

    标签: r loops dataframe data-manipulation


    【解决方案1】:

    您可以将splist设为长格式,然后将相关列与mydata合并:

    library(tidyr)
    library(dplyr)
    
    # splist to long format
    long.splist <- data.frame(splist) %>% gather(key, IDs, ID1:ID3)
    
    # merge
    merge(mydata,long.splist[,c(3,1)])
    #  IDs sample1 sample2 sample3 sample4 sample5 correct.ID
    #1   2       2       1       1       1       1          2
    #2   3       2       0       1       0       0          3
    #3   7       3       4       2       0       1          1
    #4   8       0       1       1       2       1          3
    #5  10       0       0       0       0       3         10
    #6  23       0       0       0       1       0         23
    #7  42       0       2       0       2       0         20
    #8  42       0       3       3       2       0         20
    

    结果按IDs 排序,因为这是执行连接的列。

    【讨论】:

    • 很抱歉没有更快地回复 - 这是一个更好的方法!我一直试图弄清楚如何在 sql 中以多列作为键来执行此操作,但对该环境几乎不熟悉。这正是我想要的,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-01
    • 1970-01-01
    • 2022-01-16
    • 2020-11-13
    • 2021-02-04
    • 1970-01-01
    • 2016-11-01
    相关资源
    最近更新 更多