R 数据争用-将一列中的值与其他列中的值匹配

R 数据争用-将一列中的值与其他列中的值匹配,r,R,我有以下格式的数据 Noun InCage InHouse InGarage InTree Bird Bird Dog None Cat Cat Bird Dog None Cat Dog Bird Dog None Cat 我想要这种格式: Noun Place Bird InCage Cat InTree Dog InHouse 除了

我有以下格式的数据

Noun   InCage   InHouse   InGarage   InTree
Bird   Bird     Dog       None       Cat
Cat    Bird     Dog       None       Cat
Dog    Bird     Dog       None       Cat
我想要这种格式:

Noun    Place
Bird    InCage
Cat     InTree
Dog     InHouse
除了写一堆if语句,还有什么更聪明的方法

下面是我提到的小示例的dput

structure(list(
    Item = structure(c(2L, 3L, 1L), .Label = c("Bird", "Cat", 
    "Dog"), class = "factor"), InTree = structure(c(1L, 1L, 1L
    ), .Label = "Cat", class = "factor"), InHouse = structure(c(1L, 
    1L, 1L), .Label = "Dog", class = "factor"), InCage = structure(c(1L, 
    1L, 1L), .Label = "Bird", class = "factor"), InGarage = structure(c(1L, 
    1L, 1L), .Label = "none", class = "factor")), .Names = c("Item", "InTree", 
    "InHouse", "InCage", "InGarage"
    ), row.names = c(NA, -3L), class = "data.frame")

您可以使用
tidyr
dplyr

首先,我们收集,使数据变长,而不是变宽。然后我们
过滤
以仅保留项目和动物匹配的行:

library(tidyr)
library(dplyr)
dat %>% gather(place, animal, -Item) %>%
        filter(as.character(Item) == as.character(animal))

  Item   place animal
1  Cat  InTree    Cat
2  Dog InHouse    Dog
3 Bird  InCage   Bird

一个选项是使用
apply
对数据的每一行进行操作:

cbind(df[1L], Place = apply(df, 1, FUN = function(x) names(df[-1L])[x[-1L] == x[1L]]))
#  Item   Place
#1  Cat  InTree
#2  Dog InHouse
#3 Bird  InCage

但是,对于大型数据集来说,这可能不是很快。

这将是一个相当简单的基本解决方案,使用的是针对此类问题设计的
堆栈。需要执行
as.character
步骤,因为因子变量不能很好地执行堆叠操作,因为并非所有列都共享级别:

stack( lapply(res, as.character) )

为什么不选择(-noon)然后选择distinct()?@bramtayl 1。您最终得到的
none
不是要求的。2.不太一般-如果您有一个项目不止一次怎么办?