我正在尝试在ifelse
中使用apply
语句并得到奇怪的结果。如果变量marker
是1
,我会得到预期的答案,但是当变量是> 9
时,我得到预期答案。
以下是我得到正确答案的示例数据集:
my.data <- read.table(text = '
REFNO status stage marker cumulative newstage
1018567 ccc AA 0 1 AA
1018567 aaa NONE 0 1 NONE
1018567 aaa BB 1 1 BB
1018567 bbb CC 1 1 CC
1018567 eee CC 1 1 CC
1018567 mmm CC 1 1 CC
1018567 ppp CC 1 1 CC
1019711 ddd CC 1 1 CC
', header = TRUE, stringsAsFactors = FALSE)
my.data$newstage <- apply(my.data, 1, function(x) ifelse(x['status'] == 'aaa' &
x['stage'] == 'NONE' &
x['marker'] == 0 &
x['cumulative'] > 0, 'BB', x['stage']))
my.data
下面的数据集只有一个元素与上面的元素不同,但我没有得到正确的答案。
my.data <- read.table(text = '
REFNO status stage marker cumulative newstage
1018567 ccc AA 0 1 AA
1018567 aaa NONE 0 1 NONE
1018567 aaa BB 1 1 BB
1018567 bbb CC 1 1 CC
1018567 eee CC 1 1 CC
1018567 mmm CC 1 1 CC
1018567 ppp CC 1 1 CC
1019711 ddd CC 14 1 CC
', header = TRUE, stringsAsFactors = FALSE)
my.data$newstage <- apply(my.data, 1, function(x) ifelse(x['status'] == 'aaa' &
x['stage'] == 'NONE' &
x['marker'] == 0 &
x['cumulative'] > 0, 'BB', x['stage']))
my.data
感谢您的任何建议。也许我应该使用if
语句而不是if-else
?
具体来说,我希望NONE
替换为第BB
段中的newstage
。
答案 0 :(得分:4)
如果查看apply(my.data2, 1, function(x) x)
,marker
列有两个字符而不是一个字符。这是因为两位数14
。对字符的强制使用空格填充列到其最长(大多数字符)元素的长度。这会在代码中生成" 0" == 0
,即FALSE
。但是,"0" == 0
为TRUE
" 0" == 0
# [1] FALSE
"0" == 0
# [1] TRUE
由于ifelse
已经过矢量化,因此您根本不需要使用apply
。您可以使用within
(或with
,作为akrun提及)或仅使用newstage <- ifelse(...)
within(my.data2, {
newStage <- ifelse(status == "aaa" & stage == "NONE" & marker == 0 &
cumulative > 0, "BB", stage)
})
# REFNO status stage marker cumulative newstage newStage
# 1 1018567 ccc AA 0 1 AA AA
# 2 1018567 aaa NONE 0 1 NONE BB
# 3 1018567 aaa BB 1 1 BB BB
# 4 1018567 bbb CC 1 1 CC CC
# 5 1018567 eee CC 1 1 CC CC
# 6 1018567 mmm CC 1 1 CC CC
# 7 1018567 ppp CC 1 1 CC CC
# 8 1019711 ddd CC 14 1 CC CC
答案 1 :(得分:3)
因此,当您按原样使用“应用”时,该函数会将my.data
转换为字符矩阵。当发生这种情况时,正如Richard Scriven在评论中指出的那样,你最终会在marker
列中添加额外的sapce。运行比较时,numeric
会转换为character
并且没有这个额外空格,因此请返回FALSE
。
转换为numeric
中的apply
将解决此问题。
my.data$newstage <- apply(my.data, 1, function(x) ifelse(x['status'] == 'aaa' &
x['stage'] == 'NONE' &
as.numeric(x['marker']) == 0 &
as.numeric(x['cumulative']) > 0, 'BB', x['stage']))