我在一家非盈利组织工作,有人想要一份在5年内给出100美元或以上的人的名单。跨度可以在任何地方,只要它们连续5年给出。我在计算机上同时拥有Python和R. R似乎对此更好,但我对它不是很熟悉。
我已将每件礼物的csv文件导入组织并提供给他们。
以下是csv文件中的示例行。
我无法在此处正确格式化。第一部分是标题。
我需要能够看到用户512994是否已提供100或更多,例如,2014年,2013年,2012年,2011年和2010年(连续五年)。
到目前为止,我在R脚本中有这个:
gifts <- read.csv("---------")
donors <- gifts["Gf_CnBio_ID"]
donors <- unique(donors)
我一直试图弄清楚如何制作一个较小的数据框,这是一个礼物的子集,通过捐赠者一次一个地分配礼物,然后我检查一下连续多少年那个人给了。我一直在尝试不同的方式来解决错误。
提前致谢。我的大部分背景都是用Java编写的,所以这种语言不是我以前的语言。
此外:
> library(dplyr)
> library(lubridate)
>
> set.seed(999)
>
> gifts <- read.csv("---.CSV", header = TRUE, sep = ",", )
> donors <- gifts["Donor_ID"]
> donors <- unique(donors)
>
> gifts %>%
+ mutate(gift_year = year(gifts["Gift_Date"])) %>% # extract year
+ group_by(gifts["Donor_ID"], gift_year) %>%
+ summarise(year_gift = sum(gifts["Gift_Amount"])) %>% # total gift per donor/year
+ filter(year_gift >= 100) %>%
+ group_by(bio_id) %>%
+ mutate(diff = gift_year - lag(gift_year), rle = rep( rle(diff)$lengths, rle(diff)$lengths)) %>%
+ filter(rle >= 5) %>%
+ distinct(bio_id)
Error in as.POSIXlt.default(x, tz = tz(x)) :
do not know how to convert 'x' to class “POSIXlt”
尝试运行提供的解决方案时,我一直收到错误输出。我做了一个Python程序,将日期重新格式化为yyyy-mm-dd 00:00:00格式,我仍然得到错误,所以它不是来自日期格式。我不知道造成它的原因。这是前50行。
> dput(shortExport)
structure(list(Gift_ID = c(NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, 1620192L, 1630540L, 1661287L, 1670815L, 1702338L,
1710859L, 1747572L, 1781100L, 1811188L, 1829753L, 1854499L, 1860830L,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, 1361280L, 1246941L, 1355077L, 1243748L, 1243748L, 1518414L
), Gift_Date = structure(c(2L, 23L, 32L, 10L, 17L, 19L, 33L,
44L, 45L, 11L, 27L, 30L, 47L, 3L, 26L, 9L, 18L, 31L, 37L, 22L,
28L, 16L, 25L, 34L, 39L, 21L, 42L, 1L, 29L, 35L, 43L, 6L, 13L,
4L, 5L, 38L, 41L, 46L, 15L, 24L, 40L, 2L, 12L, 20L, 14L, 7L,
8L, 8L, 36L), .Label = c("1/29/2010 0:00", "1/30/2014 0:00",
"1/31/2005 0:00", "1/31/2012 0:00", "1/31/2013 0:00", "10/11/2011 0:00",
"10/18/2000 0:00", "10/27/1998 0:00", "10/31/2005 0:00", "10/31/2011 0:00",
"10/31/2012 0:00", "11/1/2011 0:00", "11/11/2011 0:00", "11/18/1998 0:00",
"11/27/2013 0:00", "11/30/2007 0:00", "11/30/2011 0:00", "12/30/2005 0:00",
"12/30/2011 0:00", "12/6/2000 0:00", "2/27/2009 0:00", "2/28/2007 0:00",
"2/28/2011 0:00", "2/28/2014 0:00", "2/29/2008 0:00", "3/31/2005 0:00",
"3/31/2013 0:00", "4/30/2007 0:00", "4/30/2010 0:00", "4/30/2013 0:00",
"5/31/2006 0:00", "5/31/2011 0:00", "6/29/2012 0:00", "6/30/2008 0:00",
"6/30/2011 0:00", "7/18/2003 0:00", "7/31/2006 0:00", "7/31/2013 0:00",
"8/29/2008 0:00", "8/29/2014 0:00", "8/30/2013 0:00", "8/31/2009 0:00",
"8/31/2011 0:00", "8/31/2012 0:00", "9/28/2012 0:00", "9/30/2013 0:00",
"9/30/2014 0:00"), class = "factor"), Gift_Amount = c(25L, 25L,
25L, 25L, 25L, 25L, 25L, 25L, 25L, 25L, 25L, 25L, 25L, 25L, 25L,
25L, 25L, 25L, 25L, 25L, 25L, 25L, 50L, 50L, 50L, 50L, 50L, 50L,
50L, 10L, 10L, 100L, 100L, 10L, 10L, 10L, 10L, 10L, 10L, 10L,
10L, 100L, 250L, 50L, 30L, 25L, 50L, 50L, 50L), Donor_ID = c(677556L,
521512L, 521512L, 521512L, 521512L, 521512L, 521512L, 521512L,
521512L, 521512L, 521512L, 521512L, 521512L, 512994L, 512994L,
512994L, 512994L, 512994L, 512994L, 512994L, 512994L, 512994L,
512994L, 512994L, 512994L, 512994L, 512994L, 512994L, 512994L,
512994L, 512994L, 512994L, 512994L, 512994L, 512994L, 512994L,
512994L, 512994L, 512994L, 512994L, 512994L, 679277L, 406147L,
331525L, 332110L, 332110L, 263700L, 263701L, 100196L)), .Names = c("Gift_ID",
"Gift_Date", "Gift_Amount", "Donor_ID"), class = "data.frame", row.names = c(NA,
-49L))
答案 0 :(得分:3)
实现您的目标涉及链接许多操作(例如按捐赠者/年汇总,按礼物过滤&gt; $ 100等)。 dplyr
包具有很好的设施:
library(dplyr)
library(lubridate)
library(tidyr)
# gifts defined in question
gifts %>%
mutate(
gift_date = as.Date(str_sub(Gift_Date, end = -6), format = "%m/%d/%Y"),
gift_year = year(gift_date)
) %>%
group_by(Donor_ID, gift_year) %>%
summarise(year_total = sum(Gift_Amount)) %>%
filter(year_total >= 100) %>%
group_by(Donor_ID) %>%
mutate(
jump = !(gift_year == lag(gift_year) + 1 | row_number() == 1),
donor_seq = cumsum(jump) + 1,
rle = rep(rle(donor_seq)$lengths, rle(donor_seq)$lengths)
) %>%
filter(rle >= 5) %>%
distinct(Donor_ID)
答案 1 :(得分:1)
如果没有实际的样本数据集,我无法告诉您如何提取日期,但我们假设您有一个包含donorID的列,另一个包含礼品日期。然后,循环使用donorID值(或使用一个工具或另一个工具拆分数据集)并使用我自己的一个小函数seqle
,可以在github.com/cellocgw github.com/的cgwtools
包中找到cellocgw。假设您确定捐赠者在同一年内从未给过两次,那么您所要做的就是找到一个长度超过4
的序列。
示例如下。为简单起见,我使用了1到14年左右的时间以及3个捐赠者。
donmat
donor donyear
[1,] "bob" "1"
[2,] "carol" "1"
[3,] "alice" "1"
[4,] "bob" "2"
[5,] "carol" "2"
[6,] "alice" "3"
[7,] "bob" "3"
[8,] "carol" "3"
[9,] "alice" "4"
[10,] "bob" "5"
[11,] "carol" "4"
[12,] "alice" "5"
[13,] "bob" "6"
[14,] "carol" "5"
[15,] "alice" "7"
[16,] "bob" "8"
[17,] "carol" "7"
[18,] "alice" "8"
[19,] "bob" "9"
[20,] "carol" "8"
[21,] "alice" "9"
[22,] "bob" "12"
[23,] "carol" "9"
[24,] "alice" "11"
[25,] "bob" "13"
[26,] "carol" "9"
[27,] "alice" "12"
[28,] "bob" "14"
[29,] "carol" "10"
[30,] "alice" "13"
Rgames> donlen <- list()
Rgames> for(j in unique(donmat[,'donor'])) donlen[[j]] <- seqle(donmat[donmat[,'donor']==j,2])
Rgames> donlen
$bob
Run Length Encoding
lengths: int [1:4] 3 2 2 3
values : num [1:4] 1 5 8 12
$carol
Run Length Encoding
lengths: int [1:3] 5 3 2
values : num [1:3] 1 7 9
$alice
Run Length Encoding
lengths: int [1:4] 1 3 3 3
values : num [1:4] 1 3 7 11
因此,通过查看长度,我们看到“carol”有五年的序列。您可能希望使用lubridate
从日期字符串中提取年份值。