如何为数据帧的每一行计算相同值的条目?

Zwi*_*bak 2 automation loops r count dataframe

假设我有一个包含订单日期、用户 ID 和项目 ID 的大型数据框。

   order_id order_date user_id item_id
1         1 2016-06-22   30822     643
2         2 2016-06-22   30822     337
3         3 2016-06-22   30823     270
4         4 2016-06-22   30823     142
5         5 2016-06-22   30823     561
6         6 2016-06-22   30823     561
7         7 2016-06-22   30823      72
8         8 2016-06-22   30823     106
9         9 2016-06-22   30823     195
10       10 2016-06-22   30823     195
Run Code Online (Sandbox Code Playgroud)

我想要做的是计算同一用户在同一天下的订单数量以及同一用户下的同一商品的订单数量,并在第四列和第五列中显示这两个值。所以结果应该是这样的:

   order_id order_date user_id item_id same_day same_item
1         1 2016-06-22   30822     643        2         1
2         2 2016-06-22   30822     337        2         1
3         3 2016-06-22   30823     270        8         1
4         4 2016-06-22   30823     142        8         1
5         5 2016-06-22   30823     561        8         2
6         6 2016-06-22   30823     561        8         2
7         7 2016-06-22   30823      72        8         1
8         8 2016-06-22   30823     106        8         1
9         9 2016-06-22   30823     195        8         2
10       10 2016-06-22   30823     195        8         2
Run Code Online (Sandbox Code Playgroud)

或者,显示该项目是否已被多次订购的二进制变量也可以完成这项工作。我知道可以使用以下方法轻松计算每一行sum()

> sum(df$order_date=="2016-06-22" & df$user_id==30823)
[1] 8
> sum(df$item_id==561 & df$user_id==30823)
[1] 2
Run Code Online (Sandbox Code Playgroud)

但我宁愿让它自动运行,然后必须手动完成数千个条目。我真的没有想法了,非常感谢您的帮助!

Ice*_*can 6

library(data.table)
setDT(df)

df[, same_day := .N, by = .(order_date, user_id)]
df[, same_item := .N, by = .(order_date, user_id, item_id)]

df
#     order_id order_date user_id item_id same_day same_item
#  1:        1 2016-06-22   30822     643        2         1
#  2:        2 2016-06-22   30822     337        2         1
#  3:        3 2016-06-22   30823     270        8         1
#  4:        4 2016-06-22   30823     142        8         1
#  5:        5 2016-06-22   30823     561        8         2
#  6:        6 2016-06-22   30823     561        8         2
#  7:        7 2016-06-22   30823      72        8         1
#  8:        8 2016-06-22   30823     106        8         1
#  9:        9 2016-06-22   30823     195        8         2
# 10:       10 2016-06-22   30823     195        8         2
Run Code Online (Sandbox Code Playgroud)

或者用 dplyr

library(dplyr)

df <- 
 df %>% 
   add_count(order_date, user_id, name = 'same_day') %>% 
   add_count(order_date, user_id, item_id, name = 'same_item')

df
# # A tibble: 10 x 6
#    order_id order_date user_id item_id same_day same_item
#       <int> <chr>        <int>   <int>    <int>     <int>
#  1        1 2016-06-22   30822     643        2         1
#  2        2 2016-06-22   30822     337        2         1
#  3        3 2016-06-22   30823     270        8         1
#  4        4 2016-06-22   30823     142        8         1
#  5        5 2016-06-22   30823     561        8         2
#  6        6 2016-06-22   30823     561        8         2
#  7        7 2016-06-22   30823      72        8         1
#  8        8 2016-06-22   30823     106        8         1
#  9        9 2016-06-22   30823     195        8         2
# 10       10 2016-06-22   30823     195        8         2
Run Code Online (Sandbox Code Playgroud)


Tho*_*ing 5

这是使用的基本 R 解决方案 ave

df$same_day <- with(df,ave(item_id,order_date,user_id,FUN = length))
df$same_item <- with(df,ave(item_id,order_date,user_id,item_id,FUN = length))
Run Code Online (Sandbox Code Playgroud)

以至于

> df
   order_id order_date user_id item_id same_day same_item
1         1 2016-06-22   30822     643        2         1
2         2 2016-06-22   30822     337        2         1
3         3 2016-06-22   30823     270        8         1
4         4 2016-06-22   30823     142        8         1
5         5 2016-06-22   30823     561        8         2
6         6 2016-06-22   30823     561        8         2
7         7 2016-06-22   30823      72        8         1
8         8 2016-06-22   30823     106        8         1
9         9 2016-06-22   30823     195        8         2
10       10 2016-06-22   30823     195        8         2
Run Code Online (Sandbox Code Playgroud)


cam*_*lle 5

两种dplyr做法。

第一个是创建组并添加具有相应观察数量的变量:

library(dplyr)

df %>%
  group_by(user_id) %>%
  mutate(same_day = length(order_date)) %>%
  group_by(user_id, item_id) %>%
  mutate(same_item = length(item_id))
#> # A tibble: 10 x 6
#> # Groups:   user_id, item_id [8]
#>    order_id order_date user_id item_id same_day same_item
#>       <int> <fct>        <int>   <int>    <int>     <int>
#>  1        1 2016-06-22   30822     643        2         1
#>  2        2 2016-06-22   30822     337        2         1
#>  3        3 2016-06-22   30823     270        8         1
#>  4        4 2016-06-22   30823     142        8         1
#>  5        5 2016-06-22   30823     561        8         2
#>  6        6 2016-06-22   30823     561        8         2
#>  7        7 2016-06-22   30823      72        8         1
#>  8        8 2016-06-22   30823     106        8         1
#>  9        9 2016-06-22   30823     195        8         2
#> 10       10 2016-06-22   30823     195        8         2
Run Code Online (Sandbox Code Playgroud)

第二种是创建两个汇总表,一个用于same_daysame_item。汇总表只有与汇总值一样多的行,然后通过左连接重复。这就像 SQL 子查询一样,如果您熟悉的话。

df %>%
  left_join(
    df %>%
      count(user_id, name = "same_day"),
    by = "user_id"
  ) %>%
  left_join(
    df %>%
      count(user_id, item_id, name = "same_item"),
    by = c("user_id", "item_id")
  )
# same output
Run Code Online (Sandbox Code Playgroud)