R1:nrow(),循环正常,但返回NULL



**问题循环**

一个只返回[1]FALSE结果,但循环1:nrow(数据集(的循环。当年份等于1987,月份等于第三个月时,应设置FALSE。

souvenir_festival<- c(n)
for(i in 1:nrow(souvenirs)){
if (as.numeric(year(yearmonth(souvenirs$Month))) == 1987) {
souvenir_festival[i] <- FALSE
}
else if (!as.numeric(month(souvenirs$Month)) == 3) {
souvenir_festival[i] <- TRUE
}
}

Greg的建议代码:

souvenir_festival <- !(month(souvenirs$Month) == 3 & year(yearmonth(souvenirs$Month)) == 1987)
length(souvenir_festival)

我进行了内环测试,月=3,但sf仍然是1行,例如,长度(souvener_festival(

**DPUT数据**


structure(list(Month = structure(c(6209, 6240, 6268, 6299, 6329, 
6360, 6390, 6421, 6452, 6482, 6513, 6543, 6574, 6605, 6634, 6665, 
6695, 6726, 6756, 6787, 6818, 6848, 6879, 6909, 6940, 6971, 6999, 
7030, 7060, 7091, 7121, 7152, 7183, 7213, 7244, 7274, 7305, 7336, 
7364, 7395, 7425, 7456, 7486, 7517, 7548, 7578, 7609, 7639, 7670, 
7701, 7729, 7760, 7790, 7821, 7851, 7882, 7913, 7943, 7974, 8004, 
8035, 8066, 8095, 8126, 8156, 8187, 8217, 8248, 8279, 8309, 8340, 
8370, 8401, 8432, 8460, 8491, 8521, 8552, 8582, 8613, 8644, 8674, 
8705, 8735), class = c("yearmonth", "vctrs_vctr")), Sales = c(1664.81, 
2397.53, 2840.71, 3547.29, 3752.96, 3714.74, 4349.61, 3566.34, 
5021.82, 6423.48, 7600.6, 19756.21, 2499.81, 5198.24, 7225.14, 
4806.03, 5900.88, 4951.34, 6179.12, 4752.15, 5496.43, 5835.1, 
12600.08, 28541.72, 4717.02, 5702.63, 9957.58, 5304.78, 6492.43, 
6630.8, 7349.62, 8176.62, 8573.17, 9690.5, 15151.84, 34061.01, 
5921.1, 5814.58, 12421.25, 6369.77, 7609.12, 7224.75, 8121.22, 
7979.25, 8093.06, 8476.7, 17914.66, 30114.41, 4826.64, 6470.23, 
9638.77, 8821.17, 8722.37, 10209.48, 11276.55, 12552.22, 11637.39, 
13606.89, 21822.11, 45060.69, 7615.03, 9849.69, 14558.4, 11587.33, 
9332.56, 13082.09, 16732.78, 19888.61, 23933.38, 25391.35, 36024.8, 
80721.71, 10243.24, 11266.88, 21826.84, 17357.33, 15997.79, 18601.53, 
26155.15, 28586.52, 30505.41, 30821.33, 46634.38, 104660.67)), row.names = c(NA, 
-84L), key = structure(list(.rows = structure(list(1:84), ptype = integer(0), class = c("vctrs_list_of", 
"vctrs_vctr", "list"))), row.names = c(NA, -1L), class = c("tbl_df", 
"tbl", "data.frame")), index = structure("Month", ordered = TRUE), index2 = "Month", interval = structure(list(
year = 0, quarter = 0, month = 1, week = 0, day = 0, hour = 0, 
minute = 0, second = 0, millisecond = 0, microsecond = 0, 
nanosecond = 0, unit = 0), .regular = TRUE, class = c("interval", 
"vctrs_rcrd", "vctrs_vctr")), class = c("tbl_ts", "tbl_df", "tbl", 
"data.frame"))

以下是您的代码的固定版本:

sf <- logical(nrow(souvenirs))
for(i in 1:nrow(souvenirs)){
if (year(souvenirs$Month[i]) == 1987 & month(souvenirs$Month[i]) == 3) {
sf[i] <- FALSE
} else {
sf[i] <- TRUE
}
}
sf
#  [1]  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
# [17]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
# [33]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
# [49]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
# [65]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
# [81]  TRUE  TRUE  TRUE  TRUE

对于相同的结果,一个更简洁高效的版本:

sf <- !(month(souvenirs$Month) == 3 & year(souvenirs$Month) == 1987)

以下是问题的分类:

sf <- c(n) 
## n is not defined. 
## If we assume n <- nrow(souvenirs), this is still bad because then we 
## have basically sf <- 84. The goal for `sf` should be for it to be 
## class logical and have length equal to the number of rows, hence
## sf <- logical(nrow(souvenirs))  # is good
for(i in 1:nrow(souvenirs)){
# your `Month` column is already yearmonth class.
# year(souvenirs$Month) returns a numeric year, the as.numeric()` and yearmonth()` are pointless
# ditto below, month(souvenirs$Month) returns the numeric month - nothing more needed

# If you have a loop over `i`, you should expect to use `i` in the loop.
# You do use it for the ouptut, but not for the input. 
# souvenirs$Month is the whole column. But in a loop you're trying to test
# one value at a time, so you need to use `souvenirs$Month[i]`

if (as.numeric(year(yearmonth(souvenirs$Month))) == 1987) {
if (as.numeric(month(souvenirs$Month)) == 3) {
sf[i] <- FALSE
}
else {
sf[i] <- TRUE
}
}
# Your nesting structure is messing you up here.
# The else{} only pertains to the *inner* if(month == 3).
# This inner if(month == 3) only is run if the outer if(year == 1987) is true.
# So if the year isn't 1987, the inner if(){}else{} is never run, and 
# the TRUE result is never assigned.
# If you want to check two conditions simultaneously, the AND operator `&`
# is better than two if statements.
# You could fix the nesting, e.g. (pseudocode)
# if(year == 1987) {
#   if(month == 3) {
#     sf[i] <- TRUE
#   }
# }  ## Note that we close both inner AND outer if(){} before the else{} 
# else {
#   sf[i] <- FALSE
# }
# But the `&` is much cleaner
}
nrow(sf)
## sf is a vector, it doesn't have rows. Use `length()`

更一般地说,如果您的代码是if(X is TRUE) {TRUE} else {FALSE},那么编写X的方法真的很长——您想要与X相同的东西。这里,您的代码是if(X is TRUE) {FALSE} else {TRUE},可以写成!X。多亏了R的矢量化,我的版本就是这样工作的:sf <- !(month(souvenirs$Month) == 3 & year(souvenirs$Month) == 1987)

最新更新