Use of ifelse to assign values to a new dataframe column in R

做~自己de王妃 提交于 2021-02-20 18:52:08

问题


I have a time series dataframe and would like to create a new numeric column with values which are a function of an existing numeric column and which are assigned according to the day of the week column.

For example, I would require something like the following code:

Day <- c("Mo", "Mo", "Mo", "Tu", "Tu", "We", "We", "We", "We", "Th")
Val <- c(1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000)
df <- data.frame(cbind(Day,Val))
df$Adj <- ifelse(df$Day == "Mo" || df$Day == "Tu", 
                 as.numeric(levels(df$Val)) + 1, 
                 as.numeric(levels(df$Val)) + 2)

to return:

   Day  Val  Adj
1   Mo 1000 1001
2   Mo 1000 1001
3   Mo 1000 1001
4   Tu 1000 1001
5   Tu 1000 1001
6   We 1000 1002
7   We 1000 1002
8   We 1000 1002
9   We 1000 1002
10  Th 1000 1002

Unfortunately for me, my code instead returns Adj as a column of 1001s only.

   Day  Val  Adj
1   Mo 1000 1001
2   Mo 1000 1001
3   Mo 1000 1001
4   Tu 1000 1001
5   Tu 1000 1001
6   We 1000 1001
7   We 1000 1001
8   We 1000 1001
9   We 1000 1001
10  Th 1000 1001

I've tested the ifelse on one of the "We" rows and it does the trick ...

> ifelse(df$Day[6] == "Mo" || df$Day[6] == "Tu", 
+        as.numeric(levels(df$Val[6])) + 1, 
+        as.numeric(levels(df$Val[6])) + 2)
[1] 1002

... but I can't seem to get it to work on an entire column, which I had understood is one of the advantages of the ifelse function over a looped if-else statement.

I'm basing my approach off of the most similar questions I could find (Create new column in dataframe using if {} else {} in R) but have had no joy. What am I missing here?


回答1:


With dplyr:

Day <- c("Mo", "Mo", "Mo", "Tu", "Tu", "We", "We", "We", "We", "Th")
Val <- c(1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000)
df <- data.frame(Day,Val)

library(dplyr)

df %>% rowwise %>% mutate(Adj = ifelse(Day == "Mo" || Day == "Tu", 
                           Val + 1, 
                           Val + 2))
#> # A tibble: 10 x 3
#>    Day     Val   Adj
#>    <chr> <dbl> <dbl>
#>  1 Mo     1000  1001
#>  2 Mo     1000  1001
#>  3 Mo     1000  1001
#>  4 Tu     1000  1001
#>  5 Tu     1000  1001
#>  6 We     1000  1002
#>  7 We     1000  1002
#>  8 We     1000  1002
#>  9 We     1000  1002
#> 10 Th     1000  1002

Note that df <- data.frame(cbind(Day,Val)) converts Val to character which is probably not what you're looking for.
You can simplify this to df <- data.frame(Day,Val)




回答2:


We can use %in% to check if Day has value as c('Mo', 'Tu'), add 1 or 2 accordingly to Val.

df <- transform(df, Adj = Val + ifelse(Day %in% c('Mo', 'Tu'), 1, 2))
#you can do this without `ifelse` as well.
#df <- transform(df, Adj = Val + as.integer(!Day %in% c('Mo', 'Tu')) + 1)
df

#   Day  Val  Adj
#1   Mo 1000 1001
#2   Mo 1000 1001
#3   Mo 1000 1001
#4   Tu 1000 1001
#5   Tu 1000 1001
#6   We 1000 1002
#7   We 1000 1002
#8   We 1000 1002
#9   We 1000 1002
#10  Th 1000 1002



回答3:


In attempting to respect this experience level associated with this question, those functions using loops that were used in the question were also used in providing the answer. One way to achieve the desired results can be done with the following code:

Adj <- list()                                       # assign an empty list

for(i in 1: nrow(df)) {                             # For loop
   
    if(df$Day[i] == "Mo" || df$Day[i] == "Tu") {     # the conditional ifelse loop
       Adj[i] <- c(1000 + 1)                         # The 1000 can be replaced w/ Val[i] 
  } else { 
       Adj[i] <- c(1000 + 2)
    }
   }

Adj <- as.numeric(paste0(Adj))                        # Convert list to numeric vector

df <- cbind(df, Adj)                                 # Combine the df with the new vector
df                                                    # print results

The outcome can be viewed from this link:



来源:https://stackoverflow.com/questions/63857194/use-of-ifelse-to-assign-values-to-a-new-dataframe-column-in-r

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!