gpt4 book ai didi

How to change a value from a column using ifelse()(如何使用ifElse()更改列中的值)

转载 作者:bug小助手 更新时间:2023-10-26 20:13:22 28 4
gpt4 key购买 nike



Not sure what am I missing here but ifelse is not changing a value as I would expect. I am trying to change a week value if the month and day meet a certain criteria. Instead I am getting "FALSE" where it should be 52. Example below:

我不确定我在这里遗漏了什么,但如果其他值没有像我预期的那样改变值。如果月和日满足特定条件,我会尝试更改周的值。相反,我在应该是52的地方得到了“假”。示例如下:


> a
SampleDate year month week day
1 2013-01-05 2013 January 01 05
2 2013-01-08 2013 January 02 08
3 2013-01-08 2013 January 02 08
4 2013-01-05 2013 January 01 05
5 2013-01-05 2013 January 01 05
6 2013-01-08 2013 January 02 08
7 2013-01-08 2013 January 02 08
8 2013-01-05 2013 January 01 05
9 2013-01-03 2013 January 01 03
10 2013-01-08 2013 January 02 08
11 2013-01-07 2013 January 02 07
12 2013-01-03 2013 January 01 03
13 2013-01-03 2013 January 01 03
14 2013-01-08 2013 January 02 31
15 2013-01-07 2013 January 02 07
16 2013-01-03 2013 January 01 31
>
> ## "FALSE" should be 52
> with(a, ifelse(month == 'January' & day == 31, week == 52, week))
[1] "01" "02" "02" "01" "01" "02" "02" "01" "01"
[10] "02" "02" "01" "01" "FALSE" "02" "FALSE"

data


a <- structure(list(SampleDate = structure(c(15710, 15713, 15713, 
15710, 15710, 15713, 15713, 15710, 15708, 15713, 15712, 15708,
15708, 15713, 15712, 15708), class = "Date"), year = c("2013",
"2013", "2013", "2013", "2013", "2013", "2013", "2013", "2013",
"2013", "2013", "2013", "2013", "2013", "2013", "2013"), month = c("January",
"January", "January", "January", "January", "January", "January",
"January", "January", "January", "January", "January", "January",
"January", "January", "January"), week = c("01", "02", "02",
"01", "01", "02", "02", "01", "01", "02", "02", "01", "01", "02",
"02", "01"), day = c("05", "08", "08", "05", "05", "08", "08",
"05", "03", "08", "07", "03", "03", "31", "07", "31")), row.names = c(NA,
-16L), class = "data.frame")

更多回答

week==52 seems out of place, and here is one great example of how "ifelse is not class-safe is breaking for you. This effectively says "if month is january and day is 31 then return a logical vector else return a character vector". Clearly not what should be happening.

Week==52似乎不合时宜,这里有一个很好的例子来说明“如果不是类安全的话就不适合你。这实际上是说”如果月是一月,天是31,那么返回一个逻辑向量,否则返回一个字符向量“。显然不应该发生这样的事情。

week==52 is filling the yes= argument, which means its values are returned when the test= (first) argument is true. If the test= vector were all TRUE, then the return value from this ifelse would be a logical vector. However, since at least one of the test conditions are false, the fact that day is a character string casts all of the return values to string, which means TRUE -> "TRUE" (or "FALSE"). Please explain what you intend the week==52 to really mean.

Week==52填充了yes=参数,这意味着当test=(第一个)参数为真时返回它的值。如果TEST=VECTOR都为真,则该IF的返回值将是一个逻辑向量。然而,由于至少有一个测试条件为假,因此day is a字符串将所有返回值转换为字符串,这意味着真->“真”(或“假”)。请解释一下你打算这一周的真正含义。

Because of this, btw, I suggest you switch from using base::ifelse to dplyr::if_else: it will fail but fail unambiguously (more clearly) and explain why what you tried to do is likely a mistake. There are rare times when I think ifelse is adequate.

由于这个原因,顺便说一句,我建议您从使用base::ifElse切换到dplyr::if_Else:它将失败,但会明确地(更清楚地)失败,并解释为什么您尝试做的事情可能是错误的。我认为如果其他条件足够的话,这种情况很少见。

I want tne numeric value of week to be 52 if month is january and day is 31. Not sure how else to explain it.

如果月是一月,天是31,我希望周的数值是52。不知道还能怎么解释。

The issue is that you were testing equality with ==. You wanted to assign to week inside of ifelse which cannot be done, the assignment must be done using = (single) (or optionally <- if not inside mutate) and must be outside of the ifelse.

问题是您测试的是==的等价性。您想要在If Else中为Week赋值,但无法完成,则必须使用=(Single)(或可选的<-如果不在Mariate中)来完成赋值,并且必须在If Else之外。

优秀答案推荐

You want to change the value of week, based on the values of month and day. Here's one way to do that:

您希望根据月和日的值更改Week的值。有一种方法可以做到这一点:


library(dplyr)

a |> mutate(week = if_else(month == 'January' & day == 31, '52', week))

SampleDate year month week day
1 2013-01-05 2013 January 01 05
2 2013-01-08 2013 January 02 08
3 2013-01-08 2013 January 02 08
4 2013-01-05 2013 January 01 05
5 2013-01-05 2013 January 01 05
6 2013-01-08 2013 January 02 08
7 2013-01-08 2013 January 02 08
8 2013-01-05 2013 January 01 05
9 2013-01-03 2013 January 01 03
10 2013-01-08 2013 January 02 08
11 2013-01-07 2013 January 02 07
12 2013-01-03 2013 January 01 03
13 2013-01-03 2013 January 01 03
14 2013-01-08 2013 January 52 31
15 2013-01-07 2013 January 02 07
16 2013-01-03 2013 January 52 31

Note that because your values for week can begin with 0, they are characters and not integers. That's why you need '52' instead of the numeric value 52.

请注意,因为Week的值可以从0开始,所以它们是字符而不是整数。这就是为什么您需要‘52’而不是数值52的原因。



Avoid using ifelse in this context, as it degrades performance significantly. You can instead subset with brackets and replace with operator <-, either directly

避免在此上下文中使用ifElse,因为它会显著降低性能。您可以用方括号替换子集,并用运算符<-替换,或者直接


a$week[with(a, month == 'January' & day == 31)] <- 52
tail(a, 3)
# SampleDate year month week day
# 14 2013-01-08 2013 January 52 31
# 15 2013-01-07 2013 January 02 07
# 16 2013-01-03 2013 January 52 31

or using within.

或在内部使用。


within(a, week[month == 'January' & day == 31] <- 52)
# SampleDate year month week day
# ...
# 14 2013-01-08 2013 January 52 31
# 15 2013-01-07 2013 January 02 07
# 16 2013-01-03 2013 January 52 31

Benchmark


set.seed(42)
a_big <- a[sample.int(nrow(a), 1e5, replace=TRUE), ]

microbenchmark::microbenchmark(
`$<-`= {a_big$week[with(a_big, month == 'January' & day == 31)] <- 52; a_big},
`[<-`= {a_big[with(a_big, month == 'January' & day == 31), 'week'] <- 52; a_big},
within= within(a_big, week[month == 'January' & day == 31] <- 52),
replace=transform(a_big, week=replace(week, month == 'January' & day == 31, 52)),
ifelse= transform(a_big, week=ifelse(month == 'January' & day == 31, 52, week)),
check='equivalent'
)

# Unit: milliseconds
# expr min lq mean median uq max neval cld
# $<- 3.001781 3.081027 3.365160 3.145184 3.226759 8.168592 100 a
# [<- 16.257779 16.576023 17.014410 16.722306 16.929968 22.539319 100 b
# within 3.241322 3.349472 3.644337 3.408018 3.492567 9.169648 100 a
# replace 19.235649 19.529915 20.830925 19.795184 20.622298 53.269445 100 c
# ifelse 91.503930 92.620180 95.014174 93.657719 97.400140 105.806779 100 d



Data:

数据:


a <- structure(list(SampleDate = structure(c(15710, 15713, 15713, 
15710, 15710, 15713, 15713, 15710, 15708, 15713, 15712, 15708,
15708, 15713, 15712, 15708), class = "Date"), year = c("2013",
"2013", "2013", "2013", "2013", "2013", "2013", "2013", "2013",
"2013", "2013", "2013", "2013", "2013", "2013", "2013"), month = c("January",
"January", "January", "January", "January", "January", "January",
"January", "January", "January", "January", "January", "January",
"January", "January", "January"), week = c("01", "02", "02",
"01", "01", "02", "02", "01", "01", "02", "02", "01", "01", "02",
"02", "01"), day = c("05", "08", "08", "05", "05", "08", "08",
"05", "03", "08", "07", "03", "03", "31", "07", "31")), row.names = c(NA,
-16L), class = "data.frame")


Another option if you want to stay in base R:

如果你想留在R基地,另一个选择是:


transform(a, week = ifelse(month == 'January' & day == 31, '52', week))
#> SampleDate year month week day
#> 1 2013-01-05 2013 January 01 05
#> 2 2013-01-08 2013 January 02 08
#> 3 2013-01-08 2013 January 02 08
#> 4 2013-01-05 2013 January 01 05
#> 5 2013-01-05 2013 January 01 05
#> 6 2013-01-08 2013 January 02 08
#> 7 2013-01-08 2013 January 02 08
#> 8 2013-01-05 2013 January 01 05
#> 9 2013-01-03 2013 January 01 03
#> 10 2013-01-08 2013 January 02 08
#> 11 2013-01-07 2013 January 02 07
#> 12 2013-01-03 2013 January 01 03
#> 13 2013-01-03 2013 January 01 03
#> 14 2013-01-08 2013 January 52 31
#> 15 2013-01-07 2013 January 02 07
#> 16 2013-01-03 2013 January 52 31

更多回答

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com