我试图将日期因素转换为可以由for循环引用的字符向量。 for循环应该替换" Day"中的NA值。数据框的列(如下所示),其值与日期相对应。
Date Time Axis1 Day Sum.A1.Daily
1 6/12/10 5:00:00 20 NA NA
2 6/12/10 5:01:00 40 NA NA
3 6/13/10 5:02:00 50 NA NA
4 6/13/10 5:03:00 10 NA NA
5 6/14/10 5:04:00 20 NA NA
6 6/14/10 5:05:00 30 NA NA
我需要将其转换为:
Date Time Axis1 Day Sum.A1.Daily
1 6/12/10 5:00:00 20 1 60
2 6/12/10 5:01:00 40 1 60
3 6/13/10 5:02:00 50 2 80
4 6/13/10 5:03:00 30 2 80
5 6/14/10 5:04:00 20 3 50
6 6/14/10 5:05:00 30 3 50
使用我当前的代码,我得到的是:
Date Time Axis1 Day Sum.A1.Daily
1 6/12/10 5:00:00 20 NA 60
2 6/12/10 5:01:00 40 NA 60
3 6/13/10 5:02:00 50 NA 80
4 6/13/10 5:03:00 30 NA 80
5 6/14/10 5:04:00 20 NA 50
6 6/14/10 5:05:00 30 NA 50
我的for循环中的某些内容出错了,它将值分配给第4列。我需要帮助理解两件事:
我是R和stackoverflow的新手 - 这个社区有多酷。如果我违反了一个基本的问题规则,请告诉我。
## read in file; define classes
## (important b/c I want R to utilize factor levels of "Date" in column 1 of .csv file)
dat <- read.csv("data.csv", header = T, ## read in file
colClasses = c("factor", "character", "integer", "integer", "integer"))
## assign values to be used by for loops
levs <- lapply(dat, levels) ## grab levels for factor variable of dates
dates <- c(levs$Date) ## creates list of dates to reference in for loop
counts <- c(1:length(dates)) ## creates vector 1:number of dates listed in file for loop 2
x <- (1:nrow(dat)) ## creates vector 1:number of rows in file
## for loop 1 will cycle through rows in file;
## for loop 2 cycle through values in "counts" variable
## if() compares value of each object in "Dates" (col. 1)
## to one of the value of one of the levels (e.g., compared to "6/22/10", not 1)
## if ==, assigns corresp. value of "counts" to the appropriate obs. of col. 4
("Day")
for (i in x) {
for (j in counts) {
if (dat[i,1] == levs[j]) {
dat[i,4] <- counts[j]
}
}
}
dat <- transform(dat, Sum.A1.Daily = ave(dat$Axis1, dat$Date, FUN = sum))
if(!file.exists("ActData.csv")) { ## Enter file name for new data
write.csv(dat, file = "ActData2.csv") ## Enter file name for new data
} else { stop("change file name")
}
print("File Cleaning Complete")
head(dat)
tail(dat)
答案 0 :(得分:1)
这是循环非常低效的问题。尝试使用矢量化方法:
dat$day <- as.numeric(factor(dat$Date))
dat$Sum.A1.Daily <- ave(dat$Axis1, dat$Date, FUN=sum)
第一个使用因子实际上是α水平向量的整数索引。在这种情况下,我们只是丢弃levels属性,只使用整数系列。
编辑:等等!你已经在transform中正确使用了它:ave
计算第二个参数类别中FUN参数的值,并返回一个与第一个参数长度相同的向量。
答案 1 :(得分:0)
您可以使用match
获取&#34; Day&#34;的值。柱。然后使用split
sapply
获取&#34; Sum.A1.Daily&#34;的值。柱。假设您的原始数据为dat
,
> within(dat, {
Day <- match(Date, levels(Date))
Sum.A1.Daily <- sapply(split(Axis1, Day), sum)[Day]
})
# Date Time Axis1 Day Sum.A1.Daily
# 1 6/12/10 5:00:00 20 1 60
# 2 6/12/10 5:01:00 40 1 60
# 3 6/13/10 5:02:00 50 2 80
# 4 6/13/10 5:03:00 30 2 80
# 5 6/14/10 5:04:00 20 3 50
# 6 6/14/10 5:05:00 30 3 50
要打破这些部分,让我们分别看看它们。首先,在列上使用match
以及列的因子级别将返回一个数字向量,其中包含列中属于每个级别的值的索引。
> (m <- with(dat, match(Date, levels(Date))))
# [1] 1 1 2 2 3 3
然后,拆分&#34; Axis1&#34; &#34;日期&#34;列并迭代以得到总和,用[m]
矢量化,我们得到以下结果。
> with(dat, sapply(split(Axis1, Date), sum)[m])
# 6/12/10 6/12/10 6/13/10 6/13/10 6/14/10 6/14/10
# 60 60 80 80 50 50
within()
允许我们对数据帧执行操作并在一次调用中返回结果。
现在,就您的代码而言,我会对您使用transform
的位置进行以下更改
dates <- lapply(dat, levels)$Date
## grab levels for factor variable of dates
counts <- match(dat$Date, levels(dat$Date))
## creates vector 1:number of dates listed in file for loop 2
for(i in seq(dates)){
for(j in seq(counts)){
if(dat$Date[j] %in% dates) dat$Day[j] <- counts[j]
}
}