在存储在多列上的数据框中查找值

Look up value in data frame stored over multiple columns

我正在尝试计算演员为电影创造的平均收入。在我的数据集中,这是由 gross 定义的,如下面的代码片段所示:

movie_title  actor_1_name     actor_2_name     actor_3_name  ...  gross
x            Christoph Waltz  Johnny Depp      Emma Stone    x    309404152
x            Mark Addy        Christopher Lee  Naomi Watts   x    73058679 
x            Will Smith       Tom Hanks        *NA*          x    179020854
x            Tony Curran      Jeremy Renner    Matt Damon    x    93417865
x            Chris Evans      Eva Green        *NA*          x    85313679
..etc  

我做的第一件事是将三个 actor_X_name 列转换为一个单独的演员姓名列,其中包含以下行:

actors <- unique(data.frame(actor_name = c(df[,"actor_1_name"], df[,"actor_2_name"], df[,"actor_3_name"])))

上面 returns 一个新的数据框,其中包含来自原始数据集的唯一演员姓名的单列。

我怎样才能最好地交互这些 ~4900 个观察结果,在 actor_X_name 的(3 个条件)中查找原始数据框中的值?目标是获取匹配行的 gross,以便我可以计算它。

鉴于您的意见:

df <- tibble::tribble(~title, ~actor_1_name, ~actor_2_name, ~actor_3_name, ~gross,
                      "A", "Christoph Waltz",  "Johnny Depp",      "Emma Stone",    309404152,
                      "B", "Mark Addy",        "Christopher Lee",  "Naomi Watts",   73058679 ,
                      "C", "Will Smith",       "Tom Hanks",        NA,            179020854,
                      "D", "Tony Curran",      "Jeremy Renner",    "Matt Damon",    93417865,
                      "E", "Chris Evans",      "Eva Green",        NA,           85313679)
df
#> # A tibble: 5 x 5
#>   title actor_1_name    actor_2_name    actor_3_name     gross
#>   <chr> <chr>           <chr>           <chr>            <dbl>
#> 1 A     Christoph Waltz Johnny Depp     Emma Stone   309404152
#> 2 B     Mark Addy       Christopher Lee Naomi Watts   73058679
#> 3 C     Will Smith      Tom Hanks       NA           179020854
#> 4 D     Tony Curran     Jeremy Renner   Matt Damon    93417865
#> 5 E     Chris Evans     Eva Green       NA            85313679

您可以通过一个 tidyr 函数实现您的目标:pivot_longer

library(tidyr)
df %>% pivot_longer(matches("actor_\d_name"))
#> # A tibble: 15 x 4
#>    title     gross name         value          
#>    <chr>     <dbl> <chr>        <chr>          
#>  1 A     309404152 actor_1_name Christoph Waltz
#>  2 A     309404152 actor_2_name Johnny Depp    
#>  3 A     309404152 actor_3_name Emma Stone     
#>  4 B      73058679 actor_1_name Mark Addy      
#>  5 B      73058679 actor_2_name Christopher Lee
#>  6 B      73058679 actor_3_name Naomi Watts    
#>  7 C     179020854 actor_1_name Will Smith     
#>  8 C     179020854 actor_2_name Tom Hanks      
#>  9 C     179020854 actor_3_name NA             
#> 10 D      93417865 actor_1_name Tony Curran    
#> 11 D      93417865 actor_2_name Jeremy Renner  
#> 12 D      93417865 actor_3_name Matt Damon     
#> 13 E      85313679 actor_1_name Chris Evans    
#> 14 E      85313679 actor_2_name Eva Green      
#> 15 E      85313679 actor_3_name NA             

使用 matches,您将选择所有以这种方式编写的列。

您对 pivot_longer 执行的操作是重塑您的数据,以便 matches 选择的列成为一个列,并且其他列的内容对每一行重复。

titlegross 将作为每一行的唯一标识符。


如果您需要计算每个演员的平均总收入,您可以使用:

library(tidyr)
library(dplyr)

df %>% 
 pivot_longer(matches("actor_\d_name"), values_to = "actor_name") %>% 
 filter(!is.na(actor_name)) %>% 
 group_by(actor_name) %>% 
 summarise(mean_gross = mean(gross), .groups = "drop")
#> # A tibble: 14 x 2
#>    actor_name      mean_gross
#>    <chr>                <dbl>
#>  1 Chris Evans      85313679 
#>  2 Christoph Waltz 309404152 
#>  3 Christopher Lee  73058679 
#>  4 Emma Stone      309404152 
#>  5 Eva Green        85313679 
#>  6 Jeremy Renner    93417865 
#>  7 Johnny Depp     309404152 
#>  8 Mark Addy        73058679 
#>  9 Matt Damon       93417865 
#> 10 Naomi Watts      73058679 
#> 11 Tom Hanks       179020854 
#> 12 Tony Curran      93417865 
#> 13 Will Smith      179020854 

请注意,我 filter 删除了 NA,因为它们没有任何意义。 同样在 pivot_longer 中,我定义了我创建的新列的名称,以便更具可读性并与您的意图保持一致。