我正在尝试按群组找到第一个/最后一个观察结果。我厌倦了R和excel(因为它在R中很慢所以我尝试了excel)。 excel 花费少于一个 秒,但 R 花了 8分钟!!! 。两者的代码逻辑几乎相同。
数据是关于购买水果的面板数据。同一购物者可以在不同的时间购买多次。 我有233,000个观察结果。数据就像(按天购物者排序第一天和第二天):
Day Shopper Choice
1 A apple
2 A apple
1 B Banana
1 C apple
2 C Banana
3 C apple
1 D berry
2 D berry
我的第一个观察代码。我想通过指标“1”(一个新列)标记组中的第一个观察结果。
for (i in 1:n)
{ ifelse (dt$shopper[i+1]==dt$shopper[i],newcol[i+1]<-0,newcol[i+1]<-1)
}
我的excel代码是: 如果(B2&LT;&GT; B1,1,0)
在相同的购物者下,我需要重新购买矩阵。定义回购:“第一次购买”的回购是“第二次购买”;回购“第二次购买”是“第三次购买”最后一次购买没有回购。对不起,这听起来像是一个扭转者。 因此,我的解决方案是获得两个选择col并将第二个col移动到上面一行,这样我就可以通过购物者/或聚合来计算回购矩阵。标记首先按组分组的所需输出应如下所示。通过选择和选择2的列,我可以通过nrow计算回购矩阵。
Day Shopper Choice tagging choice 2
1 A apple 0 *apple*
2 A apple *apple* 0
1 B Banana 0 0
1 C apple 0 Banana
2 C Banana Banana apple
3 C apple apple 0
1 D berry 0 *berry*
2 D berry *berry* 0
[更新]。如果此用户只有一次购买,则无法重新购买。如果购买是用户的最后一次购买,则不会进行回购。因此,在这种情况下,最终的回购矩阵是
second inside bracket are the probability
first apple banana berry
apple 1 (0.5) 1 0
banana 1 0 (0) 0
berry 0 0 1 (1)
下面是我在标记首次购买用户后计算回购矩阵的方法。我是排(苹果,香蕉,浆果等)和j(苹果,香蕉,浆果等)是专栏。 [速度还可以,在标记并添加附加选择列后,我重新购买矩阵为40 * 40)
for (i in 1:n){
for(j in 1:n){
repurchase_matrix[i,j]=nrow(dt[dt[,1]==i&dt[,2]==j,])}}
答案 0 :(得分:4)
首先,假设数据按add_filter( 'woocommerce_package_rates', 'hide_shipping_when_free_is_available', 10, 2 );
function hide_shipping_when_free_is_available( $rates, $package ) {
$cart_weight = WC()->cart->cart_contents_weight; // Cart total weight
// Only modify rates if free_shipping is present
if ( isset( $rates['free_shipping'] ) && $cart_weight > 80 ) { // Here your weight condition
// To unset a single rate/method, do the following. This example unsets flat_rate shipping
unset( $rates['flat_rate'] );
// To unset all methods except for free_shipping, do the following
$free_shipping = $rates['free_shipping'];
$rates = array();
$rates['free_shipping'] = $free_shipping;
}
return $rates;
}
排序,然后按Shopper
按升序排序,您可以添加一个表示购买编号的列
Day
然后将数据帧重新整形为&#34; wide&#34;格式与
df$Purchase <- unlist(with(df, tapply(Shopper, Shopper, seq_along)))
df
# Day Shopper Choice Purchase
#1 1 A apple 1
#2 2 A apple 2
#3 1 B Banana 1
#4 1 C apple 1
#5 2 C Banana 2
#6 3 C apple 3
#7 1 D berry 1
#8 2 D berry 2
最后,您计算前两次购买的回购矩阵
df.w <- reshape(df[c('Shopper', 'Choice', 'Purchase')],
idvar='Shopper', v.names='Choice', timevar='Purchase',
direction='wide')
df.w
# Shopper Choice.1 Choice.2 Choice.3
#1 A apple apple <NA>
#3 B Banana <NA> <NA>
#4 C apple Banana apple
#7 D berry berry <NA>
要计算所有购买的回购矩阵,请从每两次连续购买的回购矩阵开始
with(df.w, prop.table(table(First=Choice.1, Second=Choice.2)))
# Second
#First apple Banana berry
# apple 0.3333333 0.3333333 0.0000000
# Banana 0.0000000 0.0000000 0.0000000
# berry 0.0000000 0.0000000 0.3333333
然后添加所有矩阵以获得&#34;总计&#34;回购矩阵
repurchase <- lapply(seq(2, ncol(df.w) - 1),
function(i) table(First=df.w[[i]], Second=df.w[[i + 1]]))
repurchase <- simplify2array(repurchase)
repurchase
#, , 1
#
# Second
#First apple Banana berry
# apple 1 1 0
# Banana 0 0 0
# berry 0 0 1
#
#, , 2
#
# Second
#First apple Banana berry
# apple 0 0 0
# Banana 1 0 0
# berry 0 0 0
(绝对频率)
apply(repurchase, 1:2, sum)
# Second
#First apple Banana berry
# apple 1 1 0
# Banana 1 0 0
# berry 0 0 1
(相对频率)
答案 1 :(得分:2)
在R
中,我们可以使用dplyr
。在&#39; Shopper&#39;进行分组后,创建&#39;标记&#39;通过使用逻辑条件row_number() < 2
进行首次观察的列,并在需要时将逻辑转换为整数。
library(dplyr)
df1 %>%
group_by(Shopper) %>%
mutate(Flag = as.integer(row_number() < 2))
如果我们可以使用最低和最高日期&#39;作为标识符,然后使用基于它的逻辑条件。
df1 %>%
group_by(Shopper) %>%
mutate(Flag = as.integer(Day %in% range(Day)))
或使用data.table
library(data.table)
setDT(df1)[, Flag := as.integer(Day %in% range(Day)), by = Shopper]
或者使用base R
,我们可以比较之前的购物者&#39;与现在的购物者&#39; (假设数据集已经订购)
i1 <- with(df1, Shopper[-1]!= Shopper[-nrow(df1)])
as.integer(c(TRUE, i1)|c(i1, TRUE))
#[1] 1 1 1 1 0 1 1 1
所有这些方法都应该比OP代码中的for
循环更快。
根据更新的预期输出,如果我们需要用&#34; 0&#34;替换第一次观察如果其他人保持不变,可以使用ifelse
或replace
并使用lead
标记&#39;,我们会创建&#39; tagChoice2&#39; ;
df1 %>%
group_by(Shopper) %>%
mutate(tagging = ifelse(row_number()==1, "0", as.character(Choice)),
tagChoice2 = lead(tagging, default = "0"))
# Day Shopper Choice tagging tagChoice2
# <int> <chr> <chr> <chr> <chr>
#1 1 A apple 0 apple
#2 2 A apple apple 0
#3 1 B Banana 0 0
#4 1 C apple 0 Banana
#5 2 C Banana Banana apple
#6 3 C apple apple 0
#7 1 D berry 0 berry
#8 2 D berry berry 0
答案 2 :(得分:1)
我一直在寻找通过分组查找列的第一个和最后一个值的答案
在data.table
中。在四处寻找并思考之后,就可以开始了。
要按组创建行顺序:
library(data.table)
DT <- data.table(col1 = rep(LETTERS[1:2], each = 4), col2 = c(3,12,5,56,6,678,233,70))
setorder(DT, col1, col2)
DT
col1 col2
1: A 3
2: A 5
3: A 12
4: A 56
5: B 6
6: B 70
7: B 233
8: B 678
DT[, rank := order(col2), by = col1]
DT
col1 col2 rank
1: A 3 1
2: A 5 2
3: A 12 3
4: A 56 4
5: B 6 1
6: B 70 2
7: B 233 3
8: B 678 4
要按组创建第一个和最后一个值:
DT[, first_val := col2[1], by = col2]
DT[, last_val := col2[.N], by = col1]
DT
col1 col2 rank first_val last_val
1: A 3 1 3 56
2: A 5 2 3 56
3: A 12 3 3 56
4: A 56 4 3 56
5: B 6 1 6 678
6: B 70 2 6 678
7: B 233 3 6 678
8: B 678 4 6 678
答案 3 :(得分:0)
您可以尝试安装Microsoft R open作为默认R.在数学计算方面,它比R base快。因为它使用了更多内核,而R.BASE只使用一个内核来计算。