2016-02-02 4 views
1

Для образца dataframe:Новый столбец в R, используя, если заявление

df2<- structure(list(region = c("AT22", "AT13", "AT12", "AT11", "AT33", 
           "AT31", "AT21", "AT34", "AT32", "BE21", "BE10", "BE24", "BE31", 
           "BE25", "BE23", "BE32", "BE33", "BE22", "BE34", "BE35"), N = c(241L, 
                           346L, 306L, 55L, 139L, 311L, 107L, 79L, 119L, 244L, 143L, 146L, 
                           59L, 212L, 203L, 223L, 173L, 147L, 54L, 75L), freq.1 = c(62L, 
                                         104L, 64L, 20L, 24L, 78L, 23L, 10L, 20L, 65L, 24L, 29L, 9L, 46L, 
                                         51L, 74L, 36L, 33L, 14L, 16L), result = c(24.95, 29.97, 21.1, 
                                                    36.27, 18.38, 24.8, 21.28, 12.54, 17.21, 26.64, 16.78, 19.86, 
                                                    15.25, 21.7, 25.12, 33.18, 20.81, 22.45, 25.93, 21.33), level = c(2, 
                                                                    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2), delete = c(1, 
                                                                                     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)), .Names = c("region", 
                                                                                                       "N", "freq.1", "result", "level", "delete"), class = c("data.table", 
                                                                                                                     "data.frame"), row.names = c(NA, -20L)) 

Я хочу создать переменную с именем «удалить», который выдвигает на первый план, который наблюдения имеют «N» больше или равно 100 или «Freg. 1' больше или равно 20. в настоящее время я использую следующий код:

df$delete <- if (df$N >=100 | df$freq.1>=20) 1 else 0 

... но это ставит 1s в каждой строке - строки 8, 13, 19 и 20 должны фактически иметь 0s.

Любые идеи?

ответ

2

Один быстрый и взломанный способ сделать логический вектор двоичным: +. Это должно быть очень быстро (но не рекомендуется некоторыми экспертами).

df2[, delete:= +(N>=100|freq.1 >=20)] 

Это также может быть сделано путем обертывания с as.integer (не Hacky, и значительно быстрее).

df2[, delete:= as.integer(N>=100|freq.1 >=20)] 
df2 
#  region N freq.1 result level delete 
# 1: AT22 241  62 24.95  2  1 
# 2: AT13 346 104 29.97  2  1 
# 3: AT12 306  64 21.10  2  1 
# 4: AT11 55  20 36.27  2  1 
# 5: AT33 139  24 18.38  2  1 
# 6: AT31 311  78 24.80  2  1 
# 7: AT21 107  23 21.28  2  1 
# 8: AT34 79  10 12.54  2  0 
# 9: AT32 119  20 17.21  2  1 
#10: BE21 244  65 26.64  2  1 
#11: BE10 143  24 16.78  2  1 
#12: BE24 146  29 19.86  2  1 
#13: BE31 59  9 15.25  2  0 
#14: BE25 212  46 21.70  2  1 
#15: BE23 203  51 25.12  2  1 
#16: BE32 223  74 33.18  2  1 
#17: BE33 173  36 20.81  2  1 
#18: BE22 147  33 22.45  2  1 
#19: BE34 54  14 25.93  2  0 
#20: BE35 75  16 21.33  2  0 

код Ор не работал, как if/else не векторизации. Это сработало бы, если мы используем ifelse т.е.

df2[, delete:= ifelse(N>100|freq.1 >=20, 1, 0)] 

ifelse является удобным/каноническим вариантом и сравнительно быстро.

ПРИМЕЧАНИЕ. Примерный набор данных OP - это data.table. Таким образом, мы используем методы data.table (:=) для создания столбца (он присваивается на месте, так что будет очень быстро).

+1

Умный, добавляя + к логическому, делает его 0/1. –

+0

За исключением небольших номеров, они выглядят одинаково быстро для меня: https://gist.github.com/1beb/1285a7689184b098703f –

+1

@BrandonBertelsen Если я помню некоторые другие тесты, сделанные в прошлом, 'ifelse' отставал от – akrun

Смежные вопросы