我正在尝试在R中自动化一些数据格式。我按日期有多个人的位置(每行是一个位置,因此一个人可能有几行)。我需要转置数据,以便每个位置日期都是一列,每个人有一行。如果在当天找到个人,则在列中输入1,如果不在,则输入0。
完成此操作后,我需要找到每行中最后一个1,将该值保留为1,但将该行中的所有其他值更改为0.我能够找到哪些行和列有最终值,但我还没弄明白如何将这个函数包含在一个更大的语句中,该语句将找到这些值,然后替换不符合条件的行值。我不想单独替换每行中的值。我不需要输出告诉我哪些行/列符合我的标准。我需要找到它们的唯一原因是替换数据帧中的其他值。下面是我在phidot.org上找到的模拟数据代码,它帮助我构建了转置数据帧(由J Laake提供)。 "间隔"和"场合"创建时根据需要将位置分成不同的时间段。
# create some dummy dates from tomorrow to 20 days from today
x = c(Sys.Date()+1:20)
# extract the year and change to numeric
as.numeric(format(x, "%Y"))
# you can also extract the month and day with
as.numeric(format(x, "%m"))
as.numeric(format(x, "%d"))
# create dummy capture data; id is animal and date is the date it was captured or recaptured
df=data.frame(id=floor(runif(100,1,50)),date=runif(100,0,5000)+as.Date("1980-01-01"))
#create some dummy date intervals that are approximately every 6 months
intervals=as.Date("1979-01-01")+seq(180,15*365,182.5)
# cut the dates into intervals
occasions=cut(df$date,intervals)
#create the count table with id for rows and years for columns
ch=with(df,table(id,occasions))
我得到下表(仅显示前10行和5列):
ch[10:20,1:10]
occasions
# id 1979-06-30 1979-12-29 1980-06-29 1980-12-28 1981-06-29
# 1 0 1 0 0 0
# 2 0 1 0 0 0
# 3 0 0 0 0 0
# 4 0 0 0 0 0
# 5 0 0 0 0 0
# 6 0 0 0 0 0
# 7 0 0 0 0 0
# 9 0 0 0 0 0
# 10 0 1 0 0 0
下面是我放在一起查找每行中最后一行并将其分配给对象的代码:
last <- apply(ch,1,function(x){tail(which(x==1),1)})
last
但这里是我被困的地方。我无法弄清楚如何将数据框中的这些值保存为1,并用0&0替换数据框中的所有其他值。
最终,在有多个行的行中,我只想显示最后的1并将其余条目更改为0.所以,如果我有下表:
# id 1979-06-30 1979-12-29 1980-06-29 1980-12-28 1981-06-29
# 1 0 1 0 0 0
# 2 0 1 1 1 0
# 3 0 0 0 0 1
# 4 0 0 0 0 0
# 5 1 1 0 1 0
# 6 0 1 0 1 0
# 7 0 1 0 0 0
# 9 1 0 0 1 1
# 10 0 1 0 0 1
我想将表格更改为:
# id 1979-06-30 1979-12-29 1980-06-29 1980-12-28 1981-06-29
# 1 0 1 0 0 0
# 2 0 0 0 1 0
# 3 0 0 0 0 1
# 4 0 0 0 0 0
# 5 0 0 0 1 0
# 6 0 0 0 1 0
# 7 0 1 0 0 0
# 9 0 0 0 0 1
# 10 0 0 0 0 1
我当前的转置数据框&#34; ch&#34;是348行x 462列。每年都会添加数据,因此我希望在R中自动执行此过程,而不是每年在Excel中对其进行格式化并将其带入R进行分析。我已经在这个网站以及phidot.org和一般的互联网上查看了几个问题和答案,并且在花了几天时间之后就无法解决这个问题。提前感谢您的时间。
答案 0 :(得分:1)
或者,从你离开桌子的地方建立并使用基地R,你可以做到
.flex-container {
padding: 0;
margin: 0;
list-style: none;
display: flex;
}
.longhand {
flex-flow: wrap row;
}
.flex-item {
color: #C3D0D9;
border: 1px solid #C3D0D9;
width: 50px;
height: 50px;
font-size: 1.3em;
text-align: center;
padding: 10px;
}
答案 1 :(得分:0)
我们可以在a++ + ++b
中轻松完成此操作 - 而不是创建中间矩阵,我直接在data.frame中找到最大行:
data.table
我们现在可以找到每个ID的最后日期:
#replicate your data
df=data.frame(id=floor(runif(100,1,50)),date=runif(100,0,5000)+as.Date("1980-01-01"))
#create some dummy date intervals that are approximately every 6 months
intervals=as.Date("1979-01-01")+seq(180,15*365,182.5)
# cut the dates into intervals (I added this as a new column)
df$occasions = as.Date(as.character(cut(df$date,intervals)))
# convert to data.table
library(data.table)
setDT(df)
我们转换回一个因子,以便表示所有日期间隔:
df_last <- df[, .(last_date = max(occasions)), by = id]
然后我们将其转换为获得所需的矩阵:
df_last[, factor(as.character(last_date), levels = as.character(sort(unique(intervals))))]