2014-10-08 5 views
-1

У меня есть data.tableобновление data.table подмножество с функцией

dt2 <- data.table(urn=1:10,freq=0, freqband="") 
dt2$freqband = NA 
dt2$freq <- 1:7 #does give a warning message 
## urn freq freqband 
## 1: 1 1  NA 
## 2: 2 2  NA 
## 3: 3 3  NA 
## 4: 4 4  NA 
## 5: 5 5  NA 
## 6: 6 6  NA 
## 7: 7 7  NA 
## 8: 8 1  NA 
## 9: 9 2  NA 
##10: 10 3  NA 

я также есть функция, я желающему использовать для группы моей колонки Частотный

fn_GetFrequency <- function(numgifts) { 
    if (numgifts <5) return("<5") 
    if (numgifts >=5) return("5+") 
    return("ERROR") 
} 

Я желающему установите столбец freqband на основе этой функции. В некоторых случаях это будут все записи, в некоторых случаях это будет подмножество. Мой текущий подход (для подмножества):

dt2[dt2$urn < 9, freqband := fn_GetFrequency(freq)] 

, используя этот подход, я получаю предупреждение:

Warning message: 
In if (numgifts < 5) return("<5") : 
    the condition has length > 1 and only the first element will be used 

затем устанавливает все записи, чтобы иметь значение «< 5», а не правильное значение. Я полагаю, что мне нужно использовать какую-то функцию lapply/sapply/etc, однако я до сих пор не смог понять, как они работают, чтобы использовать их для решения моей проблемы.

Любая помощь была бы принята с благодарностью.

EDIT: Как вы можете это сделать, если используете функцию, которая требует 2 параметра?

ОБНОВЛЕНО: включить вывод dt2 после моей попытки обновления

urn freq freqband 
1: 1 1  <5 
2: 2 2  <5 
3: 3 3  <5 
4: 4 4  <5 
5: 5 5  <5 
6: 6 6  <5 
7: 7 7  <5 
8: 8 1  <5 
9: 9 2  NA 
10: 10 3  NA 

UPDATE: Я попробовал этот код и он работал, чтобы обеспечить желаемый результат, и это позволяет мне иметь функцию, я могу позвонить в других местах кода.

dt2[dt2$urn < 9, freqband := sapply(freq, fn_GetFrequency)] 
+1

Эта функция, которую вы определили, всегда будет возвращать «ERROR». Вам нужно научиться разнице между «if» и «ifelse». R не является SAS. –

+0

@BondedDust Я не получаю «ERROR» для любого из них, поскольку первое значение соответствует первому условию, возвращая таким образом «<5», что, по-моему, является каскадом значения для freqband, где выполняется подмножество. Ошибка есть чисто как уловка, если ни одно из предыдущих условий не выполняется. – Dan

ответ

1
> fn_GetFrequency <- function(numgifts) { 
+  ifelse (numgifts <5, "<5", "5+") 
+ } 
> dt2[dt2$urn < 9, freqband := fn_GetFrequency(freq)] 
> dt2 
    urn freq freqband 
1: 1 1  <5 
2: 2 2  <5 
3: 3 3  <5 
4: 4 4  <5 
5: 5 5  5+ 
6: 6 6  5+ 
7: 7 7  5+ 
8: 8 1  <5 
9: 9 2  NA 
10: 10 3  NA 

Для нескольких групп (которые, я уверен, было предложено ранее), вы должны использовать функцию findInterval. И я делаю это методом data.table, чем метод dataframe:

dt2[ urn==8, freq := -1 ] # and something to test the <0 condition 

dt2[ urn <= 8, freqband := c("ERROR", "<5", "5+")[ 
            findInterval(freq,c(-Inf, 0, 5 ,Inf))] ] 
dt2 
    urn freq freqband 
1: 1 1  <5 
2: 2 2  <5 
3: 3 3  <5 
4: 4 4  <5 
5: 5 5  5+ 
6: 6 6  5+ 
7: 7 7  5+ 
8: 8 -1 ERROR 
9: 9 2  NA 
10: 10 3  NA 
+0

, по общему признанию, это решение действительно работает для конкретного примера выше, и я был немного узким в функции, которую я использовал. Я должен был бы использовать if (numgifts> 0 & numgifts <5) return ("<5") ... так как это имело бы тогда случай возврата «ERROR», значение freq было бы <1. Но к чему, если у вас есть больше, чем 2 частотных диапазона? например 1-2,3-4,5-8,8 + – Dan

+0

Используйте 'cut' или' findInterval'. –